/* Cairn's surface, in Vestige's design language.
   The tokens, the rail, the card grammar, the control vocabulary and the
   reservation of amber are all taken from vestige/docs/design-language.md, so
   that a person moving between the two is in one product rather than two.

   Where Cairn departs, it is written down at the point of departure. */

/* `color-scheme` is the switch and `light-dark()` reads it, so every colour is
   declared once rather than as a light block and a dark block that drift.
   It must override in BOTH directions: forcing only dark leaves someone who
   chose light on a dark machine looking at the scheme they rejected. */
:root                     { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

:root {
  --bg:     light-dark(#fbfbfa, #1c1c1f);
  --rail:   light-dark(#f4f4f2, #141417);
  --panel:  light-dark(#ffffff, #232327);
  --ink:    light-dark(#1a1a19, #f2f2f4);
  --muted:  light-dark(#6b6b66, #8e8e98);
  --line:   light-dark(#e4e4e0, #2c2c32);
  --hover:  light-dark(#eaeae6, #26262c);
  --accent: light-dark(#946a08, #e5a00d);
  --danger: light-dark(#c92a2a, #ff8787);
  --warm:   light-dark(#946608, #e8b339);
  --on-accent: light-dark(#ffffff, #191910);
  --on-danger: light-dark(#ffffff, #35090c);
  --paper: #ffffff;
}

/* Deliberately a media query and not `light-dark()`. This is the frame behind
   a Brief, which renders in its own document with its own `color-scheme`
   resolved against the operating system — something this application cannot
   reach and must not touch. If the frame followed our theme instead, a reader
   who chose light on a dark machine would get the Brief's own light text on
   our light frame: a page that loaded perfectly, rendered blank. */
@media (prefers-color-scheme: dark) { :root { --paper: #14141a; } }

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }
body {
  min-height: 100vh; background: var(--bg); color: var(--ink);
  /* The Simplified-Chinese face has to be named, and named *correctly*.
     "Noto Sans SC" is the Google Fonts webfont family; the one installed on a
     Linux box is "Noto Sans CJK SC", a different family name. Naming only the
     former matched nothing, so Han glyphs fell through to generic fallback and
     Chromium picked **Noto Sans CJK JP** -- Chinese text drawn in Japanese
     letterforms, which is what "a little jank" looks like. Measured with
     CSS.getPlatformFontsForNode, not guessed.

     Both spellings are listed, plus Adobe's name for the same typeface and the
     platform faces, SC before anything that could resolve to JP or KR. */
  /* Ordered so every platform gets a *matched pair* of Latin and Han faces
     rather than one good face and one arbitrary one:

       macOS / iOS   SF Pro        + PingFang SC       (the native pair)
       Windows       Segoe UI      + Microsoft YaHei   (the native pair)
       Linux         Noto Sans     + Noto Sans CJK SC  (one superfamily)

     The order below is not the usual boilerplate, and the reason is
     fontconfig: on Linux it answers *every* family name with a substitute, so
     `Segoe UI`, `BlinkMacSystemFont`, `Roboto` and `system-ui` all resolve to
     Liberation Sans and swallow the match before a real font is reached.
     Measured with fc-match, and `-apple-system` is no exception: Blink maps
     it to the platform's system font, which on Linux is Liberation Sans
     again. So "Noto Sans" goes first, and the per-platform behaviour falls
     out of *availability* rather than out of ordering: Noto Sans is normally
     absent on macOS and Windows, so they fall straight through to SF Pro and
     Segoe UI, while a Linux box has it and gets the face that matches its
     Han.

     Liberation Sans is not a disaster, but beside Han its digits sit tight
     and light and read as a second typeface mid-sentence. Compared side by
     side, the Noto pairing was plainly better. */
  font-family:
    "Noto Sans", -apple-system,
    "Segoe UI Variable Text", "Segoe UI", BlinkMacSystemFont, system-ui, Roboto,
    "PingFang SC", "Noto Sans CJK SC", "Source Han Sans SC", "Noto Sans SC",
    "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  font-size: 15px; line-height: 1.55; -webkit-text-size-adjust: 100%;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: var(--muted); }
code { font-size: .8125em; background: var(--hover); padding: .1em .35em;
       border-radius: 4px; overflow-wrap: anywhere; }

/* -- Shell ---------------------------------------------------------------- */
/* Grid and flex items default to min-width:auto, so a horizontally scrolling
   strip pushes its whole column wider than the viewport instead of scrolling
   inside it. Both of these are load-bearing. */
.shell { display: grid; grid-template-columns: 14.5rem minmax(0, 1fr);
         min-height: 100vh; }
.shell > .content { min-width: 0; }
main { padding: 1.4rem 1.5rem 4.5rem; max-width: 110rem; }

.rail { background: var(--rail); border-right: 1px solid var(--line);
        position: sticky; top: 0; align-self: start; height: 100vh;
        display: flex; flex-direction: column; padding: 1rem .75rem; gap: .15rem; }

/* The lockup: mark then word, in that order. The word is set in a serif,
   uppercase and open-tracked, because a drawn mark wants Roman capitals beside
   it rather than a tight sans from a different century. Tracking applies after
   the last letter too, so half of it comes back as text-indent to re-centre the
   word over its own rule -- that indent is load-bearing, not decorative. */
.brand { display: flex; align-items: center; gap: .6rem; padding: .3rem .45rem 0; }
.brand img { width: 30px; height: 30px; flex: 0 0 auto; }
.brand .word { font-family: Georgia, "Times New Roman", serif; font-weight: 400;
               font-size: .9375rem; letter-spacing: .16em; text-indent: .08em;
               text-transform: uppercase; color: var(--ink); line-height: 1.2; }
.brand .desc { display: block; font-family: inherit; font-size: .6875rem;
               letter-spacing: .02em; text-transform: none; text-indent: 0;
               color: var(--muted); margin-top: .15rem; }
.rail hr { border: 0; border-top: 1px solid var(--line); margin: .85rem .3rem; }
.rail .grouphead { font-size: .625rem; text-transform: uppercase;
                   letter-spacing: .1em; color: var(--muted);
                   padding: .7rem .6rem .3rem; }
.rail a.nav { display: flex; align-items: center; gap: .55rem; padding: .42rem .6rem;
              border-radius: 7px; color: var(--ink); font-size: .8125rem; }
.rail a.nav:hover { background: var(--hover); text-decoration: none; }
.rail a.nav[aria-current="page"] { background: var(--hover); font-weight: 600; }
.rail a.nav[aria-current="page"] .ic { color: var(--accent); opacity: 1; }
.rail a.nav .ic { opacity: .55; width: 15px; height: 15px; flex: 0 0 auto;
                  fill: none; stroke: currentColor; stroke-width: 1.5;
                  stroke-linecap: round; stroke-linejoin: round; }
.rail a.nav .lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis;
                   white-space: nowrap; }
.rail .account { margin-top: auto; padding-top: .8rem; border-top: 1px solid var(--line);
                 display: flex; align-items: center; gap: .5rem; }
.rail .account .who { font-size: .8125rem; min-width: 0; overflow: hidden;
                      text-overflow: ellipsis; white-space: nowrap; }
.rail .account form { margin-left: auto; }

/* Below 60rem the rail is a horizontal strip. There is no separate mobile
   design. The descriptor goes: it is an introduction, and there is no room to
   be introduced. */
@media (max-width: 60rem) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .rail { position: static; height: auto; flex-direction: row; align-items: center;
          gap: .3rem; overflow-x: auto; padding: .55rem .75rem;
          border-right: 0; border-bottom: 1px solid var(--line);
          scrollbar-width: none; }
  .rail::-webkit-scrollbar { display: none; }
  .rail hr, .rail .grouphead, .brand .desc { display: none; }
  .rail a.nav { flex: 0 0 auto; }
  .rail .account { margin-top: 0; margin-left: auto; padding-top: 0;
                   border-top: 0; flex: 0 0 auto; }
  .rail .account .who { display: none; }
  main { padding: 1.1rem 1rem 3rem; }
}

/* -- Page furniture ------------------------------------------------------- */
/* Every page opens the same way: heading, optional one-line subtitle, optional
   chips. Three different openings is how a user learns which page they are on
   by its being differently shaped, which is the opposite of a design system. */
.phead { margin-bottom: 1.4rem; }
.phead h1 { font-size: 1.5rem; font-weight: 650; margin: 0;
            letter-spacing: -.02em; overflow-wrap: anywhere; }
.phead .sub { color: var(--muted); font-size: .8125rem; margin: .3rem 0 0;
              max-width: 48rem; }

/* A chip is a labelled count. It is never a control that picks -- that is
   `.seg`. :hover is qualified to a.chip so a count that is not a link cannot
   offer the affordance of one. */
.chips { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1rem; }
.chip { background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
        padding: .4rem .75rem; display: flex; align-items: baseline; gap: .4rem;
        color: var(--ink); }
a.chip:hover { border-color: var(--accent); text-decoration: none; }
.chip .n { font-size: .95rem; font-weight: 650; letter-spacing: -.01em; }
.chip .k { font-size: .7rem; color: var(--muted); text-transform: uppercase;
           letter-spacing: .06em; }
/* A count that needs attention -- here, a tray that is now full. */
.chip.act { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.chip.act .n, .chip.act .k { color: var(--accent); }

.notice, .error, .panel {
  border: 1px solid var(--line); border-radius: 8px; padding: .85rem 1rem;
  background: var(--panel); font-size: .875rem; margin-bottom: 1.1rem;
}
.notice { border-left: 3px solid var(--accent); }
.error  { border-left: 3px solid var(--danger); }
.panel.warn { border-left: 3px solid var(--warm); }
.notice strong, .error strong, .panel strong { color: var(--ink); }
.panel .hint, .notice .hint { font-size: .8125rem; color: var(--muted); margin: .6rem 0 0; }

.empty { border: 1px dashed color-mix(in srgb, var(--line) 70%, var(--muted));
         border-radius: 12px; padding: 2.6rem 2rem; text-align: center;
         background: var(--panel); max-width: 38rem; margin: 1.6rem auto;
         color: var(--muted); }
.empty .ic { font-size: 2rem; opacity: .4; display: block; margin-bottom: .7rem; }
.empty h3 { margin: 0 0 .45rem; font-size: 1.05rem; color: var(--ink); }
.empty p { margin: 0 auto 1.2rem; max-width: 30rem; font-size: .875rem; }
.empty .acts { display: flex; gap: .5rem; justify-content: center; flex-wrap: wrap; }

/* -- Controls ------------------------------------------------------------- */
label { display: block; font-size: .8125rem; color: var(--muted); margin-bottom: .3rem; }
input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=hidden]),
select, textarea {
  width: 100%; padding: .5rem .7rem; border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg); color: var(--ink); font: inherit;
  font-size: .875rem;
}
button, .btn {
  font: inherit; font-size: .8125rem; font-weight: 550; cursor: pointer;
  padding: .42rem .8rem; border-radius: 7px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); display: inline-block;
}
button:hover, .btn:hover { border-color: var(--accent); text-decoration: none; }
/* One primary action per view, amber-filled. Everything else is a ghost. */
button.pri, .btn.pri { background: var(--accent); border-color: var(--accent);
                       color: var(--on-accent); font-weight: 600; }
button.ghost { background: none; }
button.sm, .btn.sm { font-size: .8125rem; padding: .32rem .7rem; }
button.dgr, .btn.dgr { color: var(--danger); }
button.dgr:hover { border-color: var(--danger); }
button.solid-dgr { background: var(--danger); border-color: var(--danger);
                   color: var(--on-danger); font-weight: 600; }
button.link { border: 0; background: none; padding: 0; color: var(--muted);
              font-size: .8125rem; text-decoration: underline; font-weight: 400; }
button.link:hover { color: var(--accent); }
input:focus-visible, a:focus-visible, button:focus-visible, select:focus-visible,
summary:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
summary.as-btn { cursor: pointer; font-size: .8125rem; font-weight: 550;
  list-style: none; padding: .42rem .8rem; border: 1px solid var(--line);
  border-radius: 7px; background: var(--panel); display: inline-block; }
summary.as-btn::-webkit-details-marker { display: none; }
summary.as-btn:hover { border-color: var(--accent); }

/* A segmented control is how you pick exactly one of something -- here, which
   kind of Piece the pool shows. Chips would be the wrong shape: they read as
   independent toggles, and this is one choice of three. */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px;
       overflow-x: auto; max-width: 100%; background: var(--panel);
       scrollbar-width: none; }
.seg::-webkit-scrollbar { display: none; }
.seg > button {
  padding: .28rem .65rem; font-size: .75rem; color: var(--muted);
  border: 0; border-right: 1px solid var(--line); white-space: nowrap;
  flex: 0 0 auto; background: none; font-family: inherit; cursor: pointer;
  line-height: 1.5; border-radius: 0; font-weight: 400;
}
.seg > button:last-child { border-right: 0; }
.seg > button:hover { background: var(--hover); color: var(--ink); border-color: var(--line); }
.seg > button[aria-current] { background: var(--hover); color: var(--ink); font-weight: 600; }

/* -- Cards and forms ------------------------------------------------------ */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
        padding: 1.15rem 1.25rem; margin-bottom: 1.1rem; }
.card > h2 { font-size: 1rem; font-weight: 650; margin: 0 0 .3rem;
             letter-spacing: -.01em; }
.card .hint { color: var(--muted); font-size: .8125rem; margin: 0 0 .9rem;
              max-width: 62ch; }
.field { margin-bottom: .85rem; }
.row { display: flex; gap: .9rem; flex-wrap: wrap; }
.row > .field { flex: 1 1 13rem; min-width: 0; }
.acts { margin-top: 1rem; display: flex; gap: .5rem; align-items: center;
        flex-wrap: wrap; }
.acts .hint { margin: 0; }

table.rows { width: 100%; border-collapse: collapse; font-size: .875rem; }
table.rows th { text-align: left; font-size: .7rem; color: var(--muted);
  font-weight: 500; text-transform: uppercase; letter-spacing: .06em;
  padding: 0 .75rem .5rem; }
table.rows td { padding: .6rem .75rem; border-top: 1px solid var(--line); }
table.rows tr td:first-child { font-weight: 550; }

.shelves { display: flex; flex-wrap: wrap; gap: .4rem; margin: .2rem 0 .2rem; }
.shelf { display: inline-flex; align-items: center; gap: .45rem; margin: 0;
         padding: .3rem .65rem; border: 1px solid var(--line); border-radius: 20px;
         background: var(--panel); font-size: .8125rem; color: var(--ink);
         cursor: pointer; }
.shelf:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.shelf input { width: auto; margin: 0; accent-color: var(--accent); }
.shelf:has(input:checked) { border-color: var(--accent); }
.shelf code { background: none; padding: 0; font-size: .8125rem; }

/* Sign-in: the lockup sits above the card rather than inside it, because the
   disc is six values from --panel in the dark scheme and has to read on --bg. */
.signin { max-width: 23rem; margin: 12vh auto 0; padding: 0 1rem; }
.signin .brand { justify-content: center; margin-bottom: 1.1rem; padding: 0; }

/* -- The board ------------------------------------------------------------ */
.board { display: grid; grid-template-columns: 19rem minmax(0, 1fr); gap: 1.4rem;
         align-items: start; }
.board > * { min-width: 0; }
@media (max-width: 68rem) { .board { grid-template-columns: minmax(0, 1fr); } }

.pool { position: sticky; top: 1rem; }
@media (max-width: 68rem) { .pool { position: static; } }
.secthead { display: flex; align-items: baseline; gap: .6rem; margin: 0 0 .7rem;
            flex-wrap: wrap; }
.secthead h2 { font-size: .9375rem; font-weight: 650; margin: 0; letter-spacing: -.01em; }
.secthead .note { font-size: .75rem; color: var(--muted); }

/* What is in the hand. Notice grammar, because that is what this product
   already means by "something is happening, read this". */
.hand { border: 1px solid var(--line); border-left: 3px solid var(--line);
        border-radius: 8px; background: var(--panel); padding: .6rem .85rem;
        font-size: .8125rem; color: var(--muted); margin-bottom: 1rem;
        display: flex; align-items: center; gap: .7rem; min-height: 2.4rem; }
.hand.active { border-left-color: var(--accent); color: var(--ink); }
.hand b { font-weight: 650; }
.hand .cancel { margin-left: auto; flex: 0 0 auto; }

.pool-list { display: flex; flex-direction: column; gap: .5rem; }
@media (max-width: 68rem) {
  .pool-list { flex-direction: row; overflow-x: auto; padding-bottom: .4rem;
               scrollbar-width: thin; }
  .pool-list .slip { min-width: 15rem; flex: 0 0 auto; }
}

.slip { border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
        padding: .6rem .7rem .6rem .8rem; cursor: pointer; position: relative;
        display: grid; gap: .1rem; }
.slip:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.slip .nm { font-weight: 600; font-size: .9375rem; letter-spacing: -.01em;
            padding-right: 2.2rem; }
.slip .sub { font-size: .75rem; color: var(--muted); display: -webkit-box;
             -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.slip .tags { display: flex; gap: .35rem; margin-top: .3rem; flex-wrap: wrap; }
/* A kind mark, not a word. Small, and it says which tray the slip belongs to. */
.slip .kind { font-size: .6875rem; padding: .05rem .4rem; border-radius: 5px;
              border: 1px solid var(--line); color: var(--muted); }
.slip[data-kind="stay"] .kind { border-color: color-mix(in srgb, var(--accent) 40%, transparent);
                                color: var(--accent); }
.slip .aff { font-size: .6875rem; color: var(--muted); }
/* Selection is amber, following the reservation. */
.slip.in-hand { border-color: var(--accent);
                box-shadow: inset 0 0 0 1px var(--accent); }
.slip.placed { opacity: .45; cursor: default; }
.slip .where { font-size: .6875rem; color: var(--accent); margin-top: .2rem; }
/* The one control on a slip. Revealed on hover and on focus, permanently on
   touch -- a focused control that is still transparent is reachable by
   keyboard and invisible to the person reaching. */
.slip .read { position: absolute; top: .45rem; right: .45rem; font-size: .6875rem;
              padding: .1rem .45rem; opacity: 0; }
.slip:hover .read, .slip .read:focus, .slip .read:focus-visible { opacity: 1; }
/* Both conditions, because an emulated phone can still report hover support
   and the pool is a touch-scrolled strip below this width regardless. */
@media (hover: none), (max-width: 68rem) { .slip .read { opacity: 1; } }

.tray { margin-bottom: 1.6rem; }
.nights { display: grid; grid-template-columns: repeat(auto-fit, minmax(5.4rem, 1fr));
          gap: .4rem; }
.night { border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
         min-height: 4.6rem; padding: .45rem .4rem; cursor: pointer;
         text-align: center; display: flex; flex-direction: column; gap: .1rem;
         position: relative; }
.night .idx  { font-size: .6875rem; color: var(--muted); }
.night .date { font-size: .6875rem; color: var(--muted); }
.night .base { font-size: .8125rem; font-weight: 650; margin-top: auto;
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.night.filled { border-color: color-mix(in srgb, var(--accent) 38%, var(--line)); }
.night.filled .base { color: var(--ink); }
/* A place you *may* drop, not an alarm. Eight cells outlined in full accent
   spends the whole reservation on a hint -- and when everything is accented
   nothing is. The strong state is the one under the pointer. */
.night.target { border-style: dashed;
                border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.night:hover { background: var(--hover); }
.night.target:hover { border-color: var(--accent); }
.night .x { position: absolute; top: .1rem; right: .3rem; font-size: .75rem;
            color: var(--muted); display: none; }
.night.filled .x { display: block; }

.days { display: flex; flex-direction: column; gap: .4rem; }
.day { display: grid; grid-template-columns: 5.4rem minmax(0, 1fr); gap: .8rem;
       border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
       padding: .55rem .75rem; }
.day .head { font-size: .75rem; color: var(--muted); line-height: 1.35; }
.day .head .d { font-weight: 650; color: var(--ink); font-size: .875rem; }
.day .head .flag { color: var(--warm); font-size: .6875rem; display: block; }
.day .lane { display: flex; flex-wrap: wrap; gap: .4rem; align-items: flex-start;
             min-height: 2rem; border-left: 1px solid var(--line); padding-left: .8rem; }
.day.target { border-style: dashed;
              border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.day:hover { background: var(--hover); }
.day.target:hover { border-color: var(--accent); }
.lane .none { color: var(--muted); font-size: .75rem; align-self: center; }
.pill { display: inline-flex; align-items: center; gap: .45rem; background: var(--bg);
        border: 1px solid var(--line); border-radius: 20px;
        padding: .15rem .3rem .15rem .6rem; font-size: .8125rem; }
.pill .nm { cursor: pointer; }
.pill .nm:hover { color: var(--accent); }
.pill .aff { font-size: .6875rem; color: var(--muted); }
.pill .rm { border: 0; background: none; color: var(--muted); cursor: pointer;
            font: inherit; font-size: .875rem; line-height: 1; padding: 0 .2rem; }
.pill .rm:hover { color: var(--danger); }

/* -- The Brief drawer ----------------------------------------------------- */
.overlay { position: fixed; inset: 0; background: rgba(12,12,14,.55);
           display: none; justify-content: flex-end; z-index: 50; }
.overlay.open { display: flex; }
.drawer { background: var(--panel); width: min(46rem, 100%); display: flex;
          flex-direction: column; border-left: 1px solid var(--line); }
.drawer .head { display: flex; align-items: center; gap: .6rem;
                padding: .75rem 1rem; border-bottom: 1px solid var(--line);
                min-height: 44px; }
.drawer .head h2 { font-size: .9375rem; font-weight: 650; margin: 0; flex: 1;
                   min-width: 0; overflow: hidden; text-overflow: ellipsis;
                   white-space: nowrap; }
/* --paper, not --panel: this sits behind the Brief's own document, whose text
   colour follows the machine. See the token. */
.drawer .body { flex: 1; overflow: auto; background: var(--paper); }
.drawer .body iframe { width: 100%; height: 100%; border: 0; display: block; }
.drawer .state { padding: 2rem 1.2rem; color: var(--muted); font-size: .875rem;
                 background: var(--panel); }
.drawer .state .err { color: var(--danger); margin-bottom: .8rem; }

/* -- Dialogs -------------------------------------------------------------- */
/* One confirmation style. Two in a product is the same defect as none, because
   the user cannot learn which one they are in. */
dialog.confirm {
  border: 1px solid var(--line); border-radius: 12px; padding: 1.3rem 1.4rem;
  background: var(--panel); color: var(--ink); max-width: 27rem;
  width: calc(100% - 2rem); box-shadow: 0 16px 48px rgba(0,0,0,.28);
}
dialog.confirm::backdrop { background: rgba(12,12,14,.55); }
dialog.confirm h2 { margin: 0 0 .5rem; font-size: 1.05rem; font-weight: 650; }
dialog.confirm .body { font-size: .875rem; color: var(--muted); }
dialog.confirm .body b { color: var(--ink); font-weight: 600; }
dialog.confirm .irrev { font-size: .8125rem; color: var(--danger); margin: .7rem 0 0; }
dialog.confirm .acts { display: flex; gap: .5rem; justify-content: flex-end;
                       margin-top: 1.2rem; }

.toast { position: fixed; left: 50%; transform: translateX(-50%); bottom: 1.4rem;
         z-index: 60; background: var(--panel); color: var(--ink);
         border: 1px solid var(--line); border-left: 3px solid var(--danger);
         font-size: .8125rem; padding: .7rem 1rem; border-radius: 8px;
         display: none; max-width: min(34rem, 92vw);
         box-shadow: 0 10px 30px rgba(0,0,0,.22); }
.toast.show { display: block; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* A spot whose 归属 differs from the base covering that day. A hint, drawn as
   a hint: the affinity text is marked, nothing is blocked, nothing is hidden,
   and the pill keeps its place. Off-base is often the right answer -- a day
   trip is a day trip -- so this is warm rather than danger, and it is the only
   thing on the board that comments on a placement at all. */
.pill.off { border-style: dashed; }
.pill.off .aff { color: var(--warm); }
.pill.off .aff::before { content: "≠ "; }

/* A finished trip. Nothing is deleted or archived when a trip ends -- the plan
   is the record of it -- but it sorts last and says so, so the board you are
   packing for is not below one from two years ago. */
table.rows tr.past td { opacity: .6; }
.tag-past { font-size: .6875rem; color: var(--muted); border: 1px solid var(--line);
            border-radius: 20px; padding: .05rem .45rem; margin-left: .4rem; }
.rail a.nav.sub { padding-left: 1.7rem; font-size: .78125rem; color: var(--muted); }
.rail a.nav.sub .ic { width: 0; }
