/*
 * The sign-in page and the boards gallery.
 *
 * ── THE APP'S COLOURS, NOT A CHROME OF ITS OWN ────────────────────────────────
 *
 * Every colour here is a token from `Pages::baseCss`, which copies `LightScheme` in
 * `app/.../ui/ChalkTheme.kt`. It used to be a dark slate chrome with its own greys, which made the
 * two halves of one web app look like two products: a dark gallery you passed through on the way to
 * a warm light editor. The slate was borrowed from the BOARD, and a board's ground is the board's -
 * `board.css` draws it, core resolves it, and it is nothing to do with the furniture around it.
 *
 * Still deliberately plain. This is a list you pass through on the way to a board, not somewhere to
 * spend time; the board itself is the interface.
 */

/*
 * `hidden` has to beat a layout rule.
 *
 * The UA stylesheet says `[hidden] { display: none }`, which any rule with more specificity
 * silently defeats - and `#signin { display: flex }` below is exactly that. The sign-in panel
 * therefore stayed on screen after signing in, with the board list appearing underneath it.
 */
[hidden] {
  display: none !important;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

#bar {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem clamp(1rem, 4vw, 2rem);
  border-bottom: 1px solid var(--outline-variant);
}

/* The name and the account, stacked, filling the left - `BoardsGallery.kt`'s heading and the line
   under it. Everything that DOES something is pushed to the right by this. */
#brand {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  flex: 1;
  min-width: 0;
}

#brandmark {
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: 1.15rem;
}

#who {
  color: var(--on-surface-variant);
  font-size: 0.85rem;
  /* A long display name should not push the sign-out button off a narrow screen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#signout {
  font: inherit;
  font-size: 0.88rem;
  color: var(--on-surface);
  background: var(--fill-soft);
  border: 1px solid var(--outline);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
}

#signout:hover {
  background: var(--hover);
}

main {
  padding: clamp(1rem, 4vh, 2.5rem) clamp(1rem, 4vw, 2rem);
  max-width: 68rem;
  width: 100%;
  margin: 0 auto;
  box-sizing: border-box;
}

/*
 * The sign-in panel: a card on the page rather than prose running the width of a desktop.
 *
 * Narrow on purpose. It is one control and the sentences around it, and a paragraph 68rem wide is
 * unreadable however good the wording - so the panel is the width of the text, centred, and the
 * page's ground shows around it the way the tablet's sheet sits on its board.
 */
#signin {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 36rem;
  margin: clamp(1rem, 5vh, 3rem) auto;
  padding: clamp(1.5rem, 5vw, 2.6rem);
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: 1rem;
  box-shadow: var(--shadow-low);
}

/* The button is what somebody came for, so it gets the room a primary action gets. */
#gbutton {
  margin: 0.4rem 0 0;
  min-height: 44px;
}

#signin h1 {
  margin: 0;
  font-size: clamp(1.6rem, 6vw, 2.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.sub {
  margin: 0.7rem 0 1.6rem;
  color: var(--on-surface-variant);
  max-width: 30rem;
}

/*
 * What Chalk is, for somebody who has not signed in.
 *
 * These moved here from the shell, which used to carry a whole second stylesheet for a separate
 * landing page. That page is gone - the signed-out state of this one has exactly the audience it
 * had - and what was left was thirty lines of dead CSS and a palette that disagreed with this file.
 */
.points {
  list-style: none;
  margin: 2.2rem 0 0;
  padding: 0;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 100%;
}

.points li {
  color: var(--on-surface-variant);
  font-size: 0.95rem;
  line-height: 1.55;
  padding-left: 1rem;
  border-left: 2px solid var(--outline-variant);
}

.points b {
  color: var(--on-surface);
  font-weight: 600;
}

.note {
  color: var(--on-surface-variant);
  font-size: 0.88rem;
  text-align: center;
  margin: 1.2rem 0 0;
  padding: 0 clamp(1rem, 4vw, 2rem);
}

.section {
  margin: 0 0 0.8rem;
}

.section h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

.section p {
  margin: 0.15rem 0 0;
  color: var(--on-surface-variant);
  font-size: 0.85rem;
}

.grid {
  display: grid;
  /* auto-fill rather than auto-fit: a single board should sit at its natural width instead of
     stretching across a desktop as one enormous card. */
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: clamp(0.8rem, 2vw, 1.4rem);
  margin-bottom: 2rem;
}

/* The card is a container now: an anchor covering the thumb and title, with the menu beside it.
   A menu button inside the anchor would follow the link on every press. */
.card {
  position: relative;
}

.card-open {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  text-decoration: none;
  color: inherit;
}

.card-open:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 0.5rem;
}

.card-menu {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
}

.card-menu > summary {
  list-style: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-toolbar);
  /* A rule round it, because it sits on a THUMBNAIL and a thumbnail of a paper board is very
     nearly this colour - a pale pill on pale paper is a control nobody can find. */
  border: 1px solid var(--outline);
  color: var(--on-surface);
  cursor: pointer;
  font-size: 0.95rem;
  line-height: 1;
}

.card-menu > summary::-webkit-details-marker {
  display: none;
}

.card-menu > summary:hover {
  background: var(--surface-raised);
}

.menu-items {
  position: absolute;
  right: 0;
  top: 30px;
  min-width: 11rem;
  display: flex;
  flex-direction: column;
  padding: 0.25rem;
  border-radius: 0.6rem;
  background: var(--surface-raised);
  border: 1px solid var(--outline-variant);
  box-shadow: var(--shadow-high);
  z-index: 3;
}

.menu-items button {
  font: inherit;
  font-size: 0.88rem;
  text-align: left;
  color: var(--on-surface);
  background: transparent;
  border: 0;
  border-radius: 0.4rem;
  padding: 0.5rem 0.7rem;
  cursor: pointer;
  white-space: nowrap;
}

.menu-items button:hover {
  background: var(--hover);
}

.menu-items button.danger {
  color: var(--error);
}

a.card.new,
button.card.new {
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.card.new .thumb {
  background: var(--fill-soft);
  border: 1px dashed var(--outline);
}

.plus {
  font-size: 2rem;
  line-height: 1;
  color: var(--on-surface-variant);
}

#board-list[aria-busy='true'] {
  opacity: 0.5;
}

a.card {
  text-decoration: none;
  color: inherit;
}

a.card:hover {
  border-color: var(--outline);
  background: var(--surface-variant);
}

a.card:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: 0.8rem;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.thumb {
  aspect-ratio: 4 / 3;
  border-radius: 0.5rem;
  overflow: hidden;
  background: var(--surface-variant);
  display: grid;
  place-items: center;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.thumb.empty::after {
  content: 'empty';
  color: var(--on-surface-variant);
  font-size: 0.8rem;
}

.card h2 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  /* Two lines then ellipsis: a card in a grid must not grow to fit a long title, or the row it
     is in grows with it. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.meta {
  margin: 0;
  color: var(--on-surface-variant);
  font-size: 0.82rem;
}

@media (prefers-reduced-motion: no-preference) {
  #signout {
    transition: background 120ms ease;
  }
}

/* ---------------------------------------------------------------- shelves

   A row per group, each a fan of boards: the centred one face-on, its neighbours turned away and
   stacked behind. Vertical scrolling moves between groups, horizontal within one.

   Two custom properties are introduced here and nowhere else. --t is unavoidable: it is one number
   driving three transform functions, and there is no other sane way to push it in from script. */

.shelf {
  margin: 0 0 1.5rem;
  /* A page of shelves costs nothing to lay out while it is off screen. */
  content-visibility: auto;
  contain-intrinsic-size: auto 22rem;
}

/* ── THE HEAD SITS ABOVE THE FAN, AND HAS TO SAY SO ───────────────────────────
 *
 * `.fan-card` carries a transform, and a transform makes a stacking context: the cards are painted
 * as positioned content, above anything in the shelf that is not. So the folder's menu opened
 * BEHIND the row of boards under it - z-index on the menu could not help, because the menu was
 * competing inside its own card's context rather than with the cards.
 *
 * Positioned and raised, so the head and the cards are compared by z-index instead of by which
 * happens to paint later. Reported with a screenshot: "the drop down menu in the web ui falls
 * behind the cards".
 */
.shelf-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0 clamp(0.8rem, 3vw, 2rem) 0.4rem;
  position: relative;
  z-index: 4;
}

.shelf-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

.shelf-head p {
  margin: 0;
  flex: 1;
  color: var(--on-surface-variant);
  font-size: 0.85rem;
}

.fan {
  /* A stacking context of its own, so the per-card z-indexes app.js writes - which run into the
     thousands, because a fan is a stack and something has to be in front - stay INSIDE the fan.
     Without it they competed with the shelf head above them and won, and the folder's menu opened
     behind the row of boards. */
  position: relative;
  z-index: 0;
  --card-w: clamp(13rem, 26vw, 21rem);
  display: flex;
  list-style: none;
  margin: 0;
  padding-inline: calc(50% - var(--card-w) / 2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* Negative: this is the overlap that makes a stack out of a row. */
  gap: calc(var(--card-w) * -0.42);
  scrollbar-width: none;
  /* Room for the cards nearest the front, which are drawn larger than their layout box. */
  padding-block: 1.2rem;
}

.fan::-webkit-scrollbar {
  display: none;
}

/* ── THE PLACEMENT IS WORKED OUT IN SCRIPT, NOT HERE ──────────────────────────
 *
 * This carried `-52deg`, `1 - 0.22 * ...` and `-1.6rem` written by hand, which is the second set of
 * constants `Coverflow.kt` says at the top of itself that it exists to prevent. Worse than the
 * duplication: the numbers MATCHED and the curves did not. Core saturates a card's turn one place
 * from the middle and holds it - its own note calls that "the coverflow signature and the thing
 * most easily got wrong" - and multiplying `--t` raw meant a card three out turned 156 degrees and
 * one four and a half out had a negative scale, drawn inside out. Nothing faded, because core's
 * `alpha` had nothing here to be copied wrong.
 *
 * `paintFan` writes these four every frame from `fanPlace`, which is checked against core. What is
 * left here is only how they are applied.
 */
.fan-card {
  --t: 0;
  --turn: 0deg;
  --shrink: 1;
  --slide: 0%;
  --fade: 1;
  flex: 0 0 var(--card-w);
  scroll-snap-align: center;
  opacity: var(--fade);
  /* perspective() here rather than on the track, and this is the important one. A perspective on
     the scrolling container has its vanishing point fixed to the container, so a card at the left
     of the viewport would be sheared differently from the same card at the right - and
     preserve-3d inside an overflow container is undefined and gets flattened anyway. Per card,
     every board is foreshortened identically wherever it happens to be sitting. */
  transform:
    translateX(var(--slide))
    perspective(1400px)
    rotateY(calc(var(--turn) * -1))
    scale(var(--shrink));
  transform-style: flat;
}

/* The title fades out as a card turns away, using t squared so it needs no abs(). Opacity rather
   than display: the text stays in the accessibility tree, so a screen reader still reads every
   board even while only one is legible. */
.fan-card h2,
.fan-card .meta {
  opacity: max(0, calc(1 - var(--t) * var(--t)));
}

.fan-card .card {
  height: 100%;
}

/* The menu only on the card you could actually aim at. */
.fan-card .card-menu {
  opacity: max(0, calc(1 - var(--t) * var(--t)));
}

/* A card showing a menu is raised in `paintFan`, not here: that function writes an inline z-index
   on every card on every frame, and an inline style beats any rule in this file. This is the note
   that stops it being re-attempted from the stylesheet. */

.shelf-caption {
  margin: 0.5rem 0 0;
  text-align: center;
  font-weight: 600;
  min-height: 1.4em;
}

.new-group {
  padding: 0 clamp(0.8rem, 3vw, 2rem) 2rem;
}

.new-group button {
  background: none;
  border: 1px dashed var(--outline);
  border-radius: 999px;
  color: var(--on-surface-variant);
  padding: 0.5rem 1.1rem;
  font: inherit;
  cursor: pointer;
}

.new-group button:hover {
  border-color: var(--outline);
  color: var(--on-surface);
}

/* Only visible to a screen reader: the fan's caption is aria-hidden so a board is not announced
   twice, and this is what announces the one that settled. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  /* The positive gap is the load-bearing line. Zeroing the transform while keeping a -42% gap
     leaves a pile of cards on top of one another - broken, rather than merely flat. */
  .fan {
    gap: clamp(0.8rem, 2vw, 1.4rem);
    scroll-behavior: auto;
  }

  .fan-card {
    transform: none;
    /* And full strength, or the far cards stay faded while the fan itself is flat - which reads as
       a rendering fault rather than as a preference being honoured. `paintFan` skips writing these
       under reduced motion anyway; this is what makes the stylesheet true on its own. */
    opacity: 1;
  }

  .fan-card h2,
  .fan-card .meta,
  .fan-card .card-menu {
    opacity: 1;
  }
}

/* ---------------------------------------------------------------- the admin panel
 *
 * Built by admin.js, and only ever on this page. Plain rows and plain controls: this is a screen
 * somebody visits to change one thing and leave, so it is laid out to be read rather than to look
 * like the gallery beside it.
 */

/* The workspace switcher: a name and a caret that opens a menu, which is what the tablet shows.
   Text rather than a boxed form control, because it names where you ARE - the same reasoning that
   makes the tablet's a TextButton in the row rather than a spinner. */
#ws {
  position: relative;
}

#ws > summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.9rem;
  color: var(--primary, #23527f);
  padding: 0.3rem 0.5rem;
  border-radius: 0.5rem;
  cursor: pointer;
  white-space: nowrap;
  max-width: 40vw;
  overflow: hidden;
}

#ws > summary::-webkit-details-marker { display: none; }

/* The caret, drawn rather than typed: a glyph would pick up the font's own idea of size and
   baseline and sit differently from the tablet's. */
#ws > summary::after {
  content: '';
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
}

#ws > summary:hover { background: var(--surface-variant); }

#ws .menu-items {
  right: 0;
  top: 2rem;
  /* Above the shelves, which raise themselves so their own menus clear the cards. */
  z-index: 10;
}

#ws .menu-items button.here {
  font-weight: 600;
}

/* The tick, in the gutter, so the names still line up under one another. */
#ws .menu-items button::before {
  content: '';
  display: inline-block;
  width: 1.1em;
}

#ws .menu-items button.here::before {
  /* A real tick. Written as the CSS escape \2713 it came through a patch script as an en dash,
     which reads as a bullet rather than as "you are here". */
  content: '✓';
}

#admin {
  font: inherit;
  font-size: 0.88rem;
  color: var(--on-surface);
  background: none;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  padding: 0.25rem 0.8rem;
  cursor: pointer;
}

#admin:hover { background: var(--surface-variant); }

#admin-view {
  padding: 1.4rem clamp(1rem, 4vw, 2rem) 4rem;
  max-width: 52rem;
  width: 100%;
  margin: 0 auto;
}

.admin-head {
  display: flex;
  /* Centred, not baseline: the way back is a bordered button now, and a box aligned on the text
     baseline inside it hangs below the heading rather than sitting beside it. */
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.4rem;
}

.admin-head h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.admin-panel {
  margin: 1.8rem 0 0;
  padding: 1rem 1.1rem 1.2rem;
  border: 1px solid var(--outline-variant);
  border-radius: 0.9rem;
  background: var(--surface-raised);
}

.admin-panel h2 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
}

/* The panel's own notes read as captions under what they describe, not as centred page furniture
   the way `.note` does out in the gallery. */
.admin-panel .note {
  text-align: left;
  padding: 0;
  margin: 0.3rem 0 0;
}

.admin-panel .note.bad { color: var(--error, #9e3833); }

.admin-rows {
  margin-top: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.admin-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--outline-variant);
}

.admin-rows > .admin-row:first-child { border-top: 0; }

/* A folder that is private grows a list of people underneath it, so that row stops being a row. */
.admin-row-stack {
  display: block;
  padding: 0;
}

.admin-row-stack > .admin-row { border-top: 0; }

.admin-who {
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin-right: auto;
}

.admin-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-sub {
  color: var(--on-surface-variant);
  font-size: 0.82rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-row select {
  font: inherit;
  font-size: 0.88rem;
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--outline-variant);
  border-radius: 0.5rem;
  background: var(--surface);
  color: var(--on-surface);
}

.admin-form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.9rem;
}

.admin-form input,
.admin-form select {
  font: inherit;
  font-size: 0.92rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--outline-variant);
  border-radius: 0.6rem;
  background: var(--surface);
  color: var(--on-surface);
}

.admin-form input[type='email'],
.admin-form input[type='text'] {
  flex: 1 1 16rem;
  min-width: 0;
}

/* A field's name, beside the control rather than over it: this panel's rows are one line each and
   a stacked label would make the letterhead twice the height of the rename above it. */
.admin-field-label {
  align-self: center;
  font-size: 0.9rem;
  color: var(--on-surface-variant);
}

/* What a setting will do, under it. Shorter than a paragraph and quieter than the panel's own
   description, because it answers "and what happens to what I have already drawn". */
.admin-hint {
  margin: 0.4rem 0 0;
  font-size: 0.85rem;
  color: var(--on-surface-variant);
}

.admin-people {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1.2rem;
  padding: 0 0 0.7rem;
}

.admin-check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
}

/* The secondary actions at the foot of a panel, on one line.
   They were appended straight onto the panel as bare siblings, and `.linkish` has no horizontal
   padding and no margin - so "New workspace" and "Delete workspace" ran together into one word.
   A row with a gap, and the destructive one pushed to the far end, where a misclick has to travel
   to reach it. */
.admin-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1.4rem;
  margin-top: 0.9rem;
}

.admin-links > .danger { margin-left: auto; }

/* ---------------------------------------------------------------- asking

   ── THE PAGE ASKS ITS OWN QUESTIONS ─────────────────────────────────────────

   Every one of these was `window.prompt` or `window.confirm`: a browser dialog in the browser's
   font, at the top of the window, with the site's name over it and OK/Cancel whatever the question
   was. It works, and it belongs to a different application than the one around it - the buttons
   cannot be named for what they do, a destructive one cannot be marked as destructive, and a
   default cannot be selected for typing over.

   Asked for directly: no input dialog boxes. This is that, in the page's own tokens, and it is
   deliberately small - a scrim, a panel, a heading, one field or one sentence, and two buttons
   named for what they do. */

.scrim {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 35%);
  display: grid;
  place-items: center;
  /* Over the shelves, which raise themselves to clear the fan's own stacking. */
  z-index: 100;
  padding: 1rem;
}

.ask {
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: 0.9rem;
  box-shadow: var(--shadow-high);
  padding: 1.1rem 1.2rem;
  width: min(28rem, 100%);
  box-sizing: border-box;
}

.ask h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  font-weight: 600;
}

.ask p {
  margin: 0 0 0.9rem;
  color: var(--on-surface-variant);
  font-size: 0.92rem;
  line-height: 1.45;
}

.ask input[type='text'] {
  font: inherit;
  font-size: 0.95rem;
  width: 100%;
  box-sizing: border-box;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--outline-variant);
  border-radius: 0.6rem;
  background: var(--surface);
  color: var(--on-surface);
  margin-bottom: 0.9rem;
}

.ask input[type='text']:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* A link being handed over is read, not typed: it is selectable and wraps, and the button beside
   it does the copying. `window.prompt` was standing in for this, which is why the "Copy this link"
   dialogs had a text field nobody was meant to edit. */
.ask code {
  display: block;
  font-size: 0.85rem;
  word-break: break-all;
  background: var(--surface-variant);
  border-radius: 0.5rem;
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.9rem;
  user-select: all;
}

.ask-buttons {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.6rem;
}

/* The destructive answer reads as one, and that means the FILL: `button.primary` is a filled
   green button, so setting only a text colour on it left "Delete" looking exactly like "Create".
   A browser dialog cannot say this at all - both of its buttons are OK and Cancel whether the
   question is "rename this" or "delete everything on it". */
.ask-buttons button.primary.danger {
  background: var(--error, #9e3833);
  color: #fff;
}

/* A control that reads as text. Used for everything secondary here, so the one primary action in
   each panel is the only thing that looks like a button. */
button.linkish {
  font: inherit;
  font-size: 0.88rem;
  color: var(--primary, #23527f);
  background: none;
  border: 0;
  padding: 0.2rem 0;
  cursor: pointer;
  text-align: left;
}

button.linkish:hover { text-decoration: underline; }
button.linkish.danger { color: var(--error, #9e3833); }

button.primary {
  font: inherit;
  font-size: 0.92rem;
  padding: 0.45rem 1rem;
  border: 0;
  border-radius: 0.6rem;
  background: var(--primary, #23527f);
  color: #fff;
  cursor: pointer;
}

button.primary:disabled { opacity: 0.55; cursor: default; }

/* ── A WAY BACK IS A BUTTON, NOT A LINK ──────────────────────────────────────
 *
 * "Back to boards" was a `.linkish`, which is right for a secondary action inside a panel and
 * wrong at the top of a page: coloured text with an underline on hover is the web's word for a
 * URL, and this navigates the app rather than fetching a document. It read as a hyperlink dropped
 * beside a heading.
 *
 * Outlined rather than filled, because `button.primary` is spoken for - one filled button per
 * panel is what makes the primary action findable, and a way OUT is never that. Same metrics as
 * primary so the two sit on one baseline. */
button.back {
  font: inherit;
  font-size: 0.88rem;
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--rule, #d8d2c6);
  border-radius: 0.6rem;
  background: none;
  color: var(--ink, #2f3a3f);
  cursor: pointer;
  line-height: 1.2;
  white-space: nowrap;
}

button.back:hover { border-color: var(--primary, #23527f); color: var(--primary, #23527f); }
button.back:focus-visible { outline: 2px solid var(--primary, #23527f); outline-offset: 2px; }

/* ---------------------------------------------------------------- a shared folder
 *
 * `/g/{share}`: an index of the drawings in a folder somebody was sent. Server-rendered, so this
 * is all it needs - a heading, a list of links, and a line saying what the link is.
 */

#folder {
  max-width: 40rem;
  margin: 0 auto;
}

#folder h1 {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

#folder .sub {
  margin: 0.3rem 0 1.6rem;
  color: var(--on-surface-variant);
}

.folder-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--outline-variant);
}

.folder-list li {
  border-bottom: 1px solid var(--outline-variant);
}

.folder-list a {
  display: block;
  padding: 0.85rem 0.2rem;
  color: var(--on-surface);
  text-decoration: none;
}

.folder-list a:hover { background: var(--surface-variant); }

.folder-list .empty {
  padding: 0.85rem 0.2rem;
  color: var(--on-surface-variant);
}

#folder .note { text-align: left; padding: 0; margin-top: 1.4rem; }
