/*
Menu. One hand written stylesheet, no build step.

Two themes off one set of semantic tokens. Nothing below the token block names a
colour; everything reads a variable, which is what makes the dark theme a forty
line override rather than a second stylesheet. theme.js resolves the system
preference into the same data-theme attribute the toggle writes, so there is
exactly ONE dark block here and no chance of two copies of a palette drifting.

The house rules this file holds, all enforced by scripts/polish.mjs in BOTH
themes:

  - every inline svg carries .gl, because an svg with no size rule renders at
    300x150 and blows the header apart
  - three hover cases, never collapsed into one: HEADER links gain a border,
    FOOTER links change colour only, SURFACES carry a resting border and change
    its colour
  - nothing in a control ever wraps, and nowrap alone is not the fix: the words
    are short as well
  - nothing scrolls sideways at any width
  - toggles, never checkboxes
  - a separator between every pair of sections
  - icon medallions sit LEFT of their copy and carry a border on a light ground
  - header, main and footer are the same width
  - paired fields in a row are the same width and start on the same line
  - body text clears 4.5:1 against its own ground, in both themes
*/

/* ----------------------------------------------------------------- tokens */

:root, :root[data-theme="light"] {
  color-scheme: light;

  /* Warm rather than neutral. This is a kitchen tool, and a blue grey page
     reads like a dashboard. */
  --ground:      #faf7f2;
  --ground-2:    #f3ede4;
  --surface:     #ffffff;
  --surface-2:   #faf7f2;
  --surface-3:   #f2ebe1;
  --line:        #e9e1d5;
  --line-2:      #d6c9b6;

  --ink:         #1a1613;
  --ink-2:       #453f38;
  --muted:       #756a5f;

  --brand:       #b04a1d;
  --brand-ink:   #8b3813;
  --brand-lift:  #c2761f;    /* the far end of every brand gradient */
  --brand-soft:  #fdf3ec;
  --brand-line:  #eec7ab;
  --on-brand:    #fffaf6;

  --ok:          #15803d;
  --ok-soft:     #eefaf1;
  --ok-line:     #b6e2c3;
  --ok-ink:      #115c31;
  --warn:        #a9590a;
  --warn-soft:   #fff6e8;
  --warn-line:   #eed3a0;
  --warn-ink:    #7c3d06;
  --bad:         #b03a20;
  --bad-soft:    #fdf1ee;
  --bad-line:    #e8bdb1;
  --bad-ink:     #8a2a13;

  /* The dark utility strip and the footer share one palette. */
  --strip:       #17120f;
  --strip-2:     #221b16;
  --strip-line:  #362c24;
  --strip-ink:   #d4c6b8;
  --strip-ink-2: #a89787;
  --strip-hi:    #ffffff;
  --strip-accent:#e9a677;

  --shadow-sm: 0 1px 2px rgba(26, 22, 19, .05);
  --shadow:    0 1px 2px rgba(26, 22, 19, .05), 0 10px 26px -16px rgba(26, 22, 19, .28);
  --shadow-lg: 0 2px 6px rgba(26, 22, 19, .07), 0 26px 60px -28px rgba(26, 22, 19, .40);
  --ring:      0 0 0 3px rgba(176, 74, 29, .18);
  --sheen:     linear-gradient(180deg, rgba(255, 255, 255, .75), rgba(255, 255, 255, 0));
  --glass:     rgba(255, 255, 255, .82);

  --radius:    11px;
  --radius-lg: 16px;
  --shell:     1380px;
  --gap:       18px;

  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --display: 'Space Grotesk', 'Inter', system-ui, sans-serif;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  /* Warm charcoal, not black. Pure black with a warm accent on it looks like a
     terminal; this keeps the same room the light theme has. */
  --ground:      #14110f;
  --ground-2:    #1b1715;
  --surface:     #1e1a17;
  --surface-2:   #252019;
  --surface-3:   #2d2721;
  --line:        #352e27;
  --line-2:      #4c433a;

  --ink:         #f6f0e8;
  --ink-2:       #d8cdc0;
  --muted:       #a2968a;

  --brand:       #ef8b4f;
  --brand-ink:   #f6a97c;
  --brand-lift:  #e8b45c;
  --brand-soft:  #2e1f14;
  --brand-line:  #553927;
  --on-brand:    #1b1006;

  --ok:          #63c986;
  --ok-soft:     #14271b;
  --ok-line:     #2f5039;
  --ok-ink:      #a6e4ba;
  --warn:        #e5aa48;
  --warn-soft:   #2c2114;
  --warn-line:   #524021;
  --warn-ink:    #f0cd8d;
  --bad:         #ef8168;
  --bad-soft:    #2c1814;
  --bad-line:    #512d23;
  --bad-ink:     #f5ab98;

  --strip:       #0c0a09;
  --strip-2:     #161311;
  --strip-line:  #2c2521;
  --strip-ink:   #c2b3a4;
  --strip-ink-2: #94867a;
  --strip-hi:    #fdf8f3;
  --strip-accent:#ef8b4f;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .55);
  --shadow:    0 1px 2px rgba(0, 0, 0, .55), 0 12px 28px -18px rgba(0, 0, 0, .95);
  --shadow-lg: 0 2px 8px rgba(0, 0, 0, .6), 0 30px 70px -30px rgba(0, 0, 0, 1);
  --ring:      0 0 0 3px rgba(239, 139, 79, .26);
  --sheen:     linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, 0));
  --glass:     rgba(30, 26, 23, .82);
}

/* ------------------------------------------------------------------ reset */

*, *::before, *::after { box-sizing: border-box; }

/* The UA rule for [hidden] is display:none at the lowest specificity, so any
   class that sets a display wins and a "hidden" inline form lays out at full
   width off the side of the page. This puts it back. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  /* The scrollbar is part of the app, not part of the browser. Firefox takes
     the two colour form; everything else takes the pseudo elements below. Both
     read tokens, so the bar turns over with the theme like everything else. */
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) var(--ground-2);
}

::-webkit-scrollbar { width: 14px; height: 14px; }
::-webkit-scrollbar-track { background: var(--ground-2); }
::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 999px;
  /* The border is the track showing through, which is what gives the thumb its
     inset look instead of a slab filling the whole gutter. */
  border: 4px solid var(--ground-2);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--brand); background-clip: padding-box; }
::-webkit-scrollbar-thumb:active { background: var(--brand-ink); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: var(--ground-2); }

/* A scroller inside a panel sits on the panel's ground, not the page's. */
.panel ::-webkit-scrollbar-track, .modal ::-webkit-scrollbar-track { background: var(--surface-2); }
.panel ::-webkit-scrollbar-thumb, .modal ::-webkit-scrollbar-thumb { border-color: var(--surface-2); }

body {
  margin: 0;
  /* The footer sits at the bottom of a short page rather than halfway up it
     with a band of empty ground under it. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Sideways scroll is never the answer to a too wide element, so the page
     itself refuses it and every child that could cause one is fixed instead. */
  overflow-x: hidden;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

main { flex: 1 0 auto; }

h1, h2, h3 {
  font-family: var(--display); font-weight: 600;
  letter-spacing: -0.015em; margin: 0;
}
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img, svg { max-width: 100%; }

/* Colour and edges move; nothing that affects layout does, so a hover can
   never shift the page. */
a, button, input, textarea, .panel, .stat, .chip, .badge, .item, .hit, .railrow,
.calchip, .tab, .switch, .medallion {
  transition: background-color .14s ease, border-color .14s ease,
              color .14s ease, box-shadow .14s ease;
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* The one size rule for every glyph in the app. */
.gl { width: 1.05em; height: 1.05em; flex: none; display: inline-block; vertical-align: -0.16em; }

.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  /* Moved out of view with a transform rather than a big negative offset: an
     element parked at left:-9999px still counts as content outside the
     viewport, which is indistinguishable from a real sideways overflow. */
  position: absolute; left: 0; top: 0; z-index: 50;
  transform: translateY(-200%);
  background: var(--brand); color: var(--on-brand);
  padding: 10px 16px; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { transform: none; }

:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.muted { color: var(--muted); }

/* The single container. Header, main and footer all use it, which is what
   keeps their widths identical. */
.shell { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 24px; }

/* --------------------------------------------------------------- sections */

.band { padding: 24px 0; }
/* A separator between every pair of sections. Backgrounds inside main never
   change, so a hairline is always right here and never doubles up with a
   colour change. */
.band + .band { border-top: 1px solid var(--line); }

/* ----------------------------------------------------------------- header */

.site-header { background: var(--surface); position: relative; z-index: 20; }

.utility {
  background: var(--strip); color: var(--strip-ink);
  border-bottom: 1px solid var(--strip-line);
}
.utility-grid {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; min-height: 40px; font-size: 12.5px;
}
.utility-facts { display: flex; align-items: center; gap: 18px; min-width: 0; }
.ufact { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.ufact .gl { color: var(--strip-ink-2); }
.utility-facts .ufact:last-child { display: none; }

.utility-right { display: flex; align-items: center; gap: 10px; }
.utility-nav { display: flex; align-items: center; gap: 4px; }
.utility-nav a {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; border-radius: 8px; white-space: nowrap;
  /* Resting transparent border so the hover border cannot shift the row. */
  border: 1px solid transparent;
  color: var(--strip-ink);
}
/* HEADER links gain a border on hover. Footer links never do. */
.utility-nav a:hover {
  border-color: var(--strip-line); background: var(--strip-2); color: var(--strip-hi);
}
.utility-nav a:hover .gl { color: var(--strip-accent); }

.navbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.nav-grid {
  display: grid;
  /* 1fr auto 1fr, so the nav stays centred whatever the two outer groups do.
     A flex row with justify-center drifts the moment a label changes. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 16px; min-height: 66px;
}

/* The mark sits straight on the bar. No chip, no plate, no tile behind it. */
.wordmark {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--display); font-size: 20px; font-weight: 600;
  letter-spacing: -0.02em;
  white-space: nowrap; justify-self: start;
  border: 1px solid transparent; border-radius: 9px; padding: 4px 8px 4px 0;
}
.wordmark .gl { width: 1.3em; height: 1.3em; color: var(--brand); }
.wordmark:hover { color: var(--brand-ink); }
.wordmark:hover .gl { color: var(--brand-lift); }

.mainnav { display: flex; align-items: center; gap: 4px; justify-self: center; }
.navlink {
  position: relative;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border-radius: 9px; white-space: nowrap;
  font-weight: 500; color: var(--ink-2);
  border: 1px solid transparent;
}
.navlink .gl { color: var(--muted); }
.navlink:hover { border-color: var(--line-2); background: var(--surface-2); color: var(--ink); }
.navlink:hover .gl { color: var(--brand); }
.navlink.current {
  color: var(--brand-ink); background: var(--brand-soft); border-color: var(--brand-line);
}
.navlink.current .gl { color: var(--brand); }

.nav-actions { display: flex; align-items: center; gap: 8px; justify-self: end; }

/* ---------------------------------------------------------- theme toggle */

/* A switch, never a checkbox, and it lives in the utility strip where the
   other settings-shaped things are. */
.themetoggle {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 10px 4px 8px; border-radius: 999px;
  border: 1px solid transparent; background: transparent;
  color: var(--strip-ink); font: inherit; font-size: 12.5px;
  white-space: nowrap; cursor: pointer;
}
.themetoggle:hover { border-color: var(--strip-line); background: var(--strip-2); color: var(--strip-hi); }
.themetoggle .gl { color: var(--strip-ink-2); }
.themetoggle:hover .gl { color: var(--strip-accent); }
.themetoggle .sun { display: inline-block; }
.themetoggle .moon { display: none; }
:root[data-theme="dark"] .themetoggle .sun { display: none; }
:root[data-theme="dark"] .themetoggle .moon { display: inline-block; }

.themetoggle .switch { width: 36px; height: 20px; }
.themetoggle .switch .knob { width: 14px; height: 14px; }
.themetoggle .switch.on .knob { transform: translateX(16px); }
.themetoggle .switch {
  background: var(--strip-2); border-color: var(--strip-line);
}
.themetoggle .switch .knob { background: var(--strip-ink); border-color: var(--strip-line); }
.themetoggle .switch.on { background: var(--brand); border-color: var(--brand); }
.themetoggle .switch.on .knob { background: var(--strip-hi); border-color: var(--strip-hi); }

/* Sign Out sits in the utility strip and borrows the theme toggle's metrics, so
   it inherits the same hover border, the same no-wrap and the same 38px phone
   tap target rather than needing its own. */
.signoutform { display: contents; }
.signoutbtn { cursor: pointer; }
.signoutbtn .gl { color: var(--strip-ink-2); }
.signoutbtn:hover .gl { color: var(--strip-accent); }

/* The sign in panel is the one page a signed out visitor sees. It is centred
   and capped rather than full width, because a single pair of fields stretched
   across 1380px reads as a mistake. */
.panel-signin { max-width: 520px; margin: 0 auto; }
.signin-note {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--muted); font-size: 12.5px;
}
.signin-note .gl { color: var(--brand); }

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: 10px;
  font: inherit; font-weight: 500; white-space: nowrap; cursor: pointer;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.btn:hover {
  border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink);
  box-shadow: var(--shadow);
}
.btn .gl { color: var(--muted); }
.btn:hover .gl { color: var(--brand); }
.btn:active { box-shadow: var(--shadow-sm); }

.btn-primary {
  /* The one gradient that matters. Everything else is flat on purpose so this
     reads as the action rather than as decoration. */
  background: linear-gradient(135deg, var(--brand), var(--brand-lift));
  border-color: var(--brand); color: var(--on-brand);
  box-shadow: var(--shadow);
}
.btn-primary .gl, .btn-primary:hover .gl { color: var(--on-brand); opacity: .82; }
.btn-primary:hover {
  background: linear-gradient(135deg, var(--brand-ink), var(--brand));
  border-color: var(--brand-ink); color: var(--on-brand);
  box-shadow: var(--shadow-lg);
}

.btn-soft { background: var(--surface); }
.btn-sm { padding: 6px 11px; font-size: 13px; }
.btn-lg { padding: 12px 22px; font-size: 16px; }
.btn-icon { padding: 9px 11px; }

.btn-danger { border-color: var(--bad-line); background: var(--bad-soft); color: var(--bad-ink); }
.btn-danger .gl { color: var(--bad); }
.btn-danger:hover { border-color: var(--bad); background: var(--bad-soft); color: var(--bad-ink); }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 31px; height: 31px; padding: 0; cursor: pointer;
  border-radius: 9px; border: 1px solid transparent;
  background: transparent; color: var(--muted);
}
.iconbtn:hover { border-color: var(--line-2); background: var(--surface-3); color: var(--brand); }
.iconbtn-bad:hover { border-color: var(--bad-line); background: var(--bad-soft); color: var(--bad); }

/* ------------------------------------------------------------- page heads */

.pagehead {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}
.pagehead-copy { min-width: 0; }
.pagehead h1 { font-size: 29px; line-height: 1.1; letter-spacing: -0.025em; }
.pagehead-copy p {
  margin-top: 7px; color: var(--muted); font-size: 13.5px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pagehead-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pagehead-actions form { display: contents; }

/* ------------------------------------------------------------------ stats */

.statgrid { display: grid; gap: var(--gap); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stat {
  position: relative; overflow: hidden;
  /* Medallion LEFT of the copy, never above it. */
  display: flex; align-items: flex-start; gap: 14px;
  padding: 15px 17px; min-width: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* A hairline of brand across the top edge, lit on hover. Cheap, and it is what
   stops four boxes reading as four boxes. */
.stat::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--brand), var(--brand-lift));
  opacity: .32;
}
.stat:hover { border-color: var(--line-2); box-shadow: var(--shadow); }
.stat:hover::before { opacity: 1; }

.medallion {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none;
  border-radius: 13px;
  /* Light ground, so it carries a border. Every time, no exceptions. */
  background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--brand);
  box-shadow: inset 0 1px 0 var(--surface);
  font-size: 20px;
}
.medallion-lg { width: 58px; height: 58px; font-size: 26px; border-radius: 16px; }

.stat-copy { min-width: 0; display: flex; flex-direction: column; }
.stat-num {
  font-family: var(--display); font-size: 28px; font-weight: 600; line-height: 1.05;
  letter-spacing: -0.03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-num-sm { font-size: 20px; letter-spacing: -0.02em; }
.stat-label {
  color: var(--muted); font-size: 12.5px; margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ----------------------------------------------------------------- panels */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.panel:hover { border-color: var(--line-2); }
.panel + .panel { margin-top: var(--gap); }
.panel-narrow { max-width: 720px; }
.panel-warn { border-color: var(--warn-line); }

.panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px; padding: 14px 17px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); background-image: var(--sheen);
}
.panel-title { min-width: 0; }
.panel-title h1, .panel-title h2 {
  font-size: 16.5px; display: flex; align-items: center; gap: 8px; min-width: 0;
}
.panel-title h2 .gl { color: var(--brand); }
.panel-title h2 a:hover { color: var(--brand-ink); }
.panel-title p { color: var(--muted); font-size: 12.5px; margin-top: 4px; }
.panel-tools { display: flex; align-items: center; gap: 4px; flex: none; }
.panel-tools form { display: contents; }

.panel-body { padding: 17px; }
.panel-foot {
  padding: 12px 17px; border-top: 1px solid var(--line);
  background: var(--surface-2);
}
/* Commit point in the same place on every form: cancel left of submit, and
   anything destructive far left. It wraps rather than pushing the submit off
   the side of a phone. */
.panel-foot-form {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.foot-start, .foot-end { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.modal-foot { flex-wrap: wrap; }

/* ------------------------------------------------------------------ forms */

.fieldset { display: block; }
.fieldset + .fieldset, .fieldrow + .fieldset, .fieldset + .fieldrow { margin-top: 15px; }
.label { display: block; font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.hint { display: block; color: var(--muted); font-size: 12px; margin-top: 6px; }

/* A pair of fields is EVEN: same width, same top, and the hints under them
   start on the same line however differently they wrap.

   SUBGRID is what does it. Two sibling grids with the same row template still
   drift, because each sizes its own rows: a hint that wraps to two lines under
   one field pushes only that field's box. Sharing the parent's rows is the only
   thing that actually lines them up. */
.fieldrow {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: auto auto auto;
  gap: 15px; align-items: start;
}
.fieldrow > .fieldset {
  display: grid; grid-row: span 3; grid-template-rows: subgrid;
  gap: 0; margin-top: 0; min-width: 0;
}
/* The wide row is a field beside the sentence explaining it, not a pair of
   fields, so it keeps ordinary rows and bottom aligns instead. */
.fieldrow-wide { grid-template-rows: auto; }
.fieldrow-wide > .fieldset { display: block; grid-row: auto; }
/* Without subgrid the two columns still hold the same sized boxes; only the
   hints can fall out of line. */
@supports not (grid-template-rows: subgrid) {
  .fieldrow > .fieldset { grid-row: auto; grid-template-rows: auto auto auto; }
}

.field {
  width: 100%; min-width: 0; font: inherit; color: var(--ink);
  padding: 9px 12px; border-radius: 10px;
  border: 1px solid var(--line-2); background: var(--surface);
  box-shadow: var(--shadow-sm);
  /* A date or time input carries its own intrinsic width and its own padding
     for the picker glyph, which is exactly how two "equal" columns end up
     holding two different sized boxes. */
  -webkit-appearance: none; appearance: none;
}
.field::-webkit-date-and-time-value { text-align: left; }
.field::-webkit-calendar-picker-indicator { opacity: .5; cursor: pointer; }
.field:hover::-webkit-calendar-picker-indicator { opacity: 1; }
.field::placeholder { color: var(--muted); opacity: .8; }
.field:hover { border-color: var(--brand-line); }
.field:focus { border-color: var(--brand); outline: none; box-shadow: var(--ring); }
.field-area { resize: vertical; min-height: 78px; -webkit-appearance: auto; appearance: auto; }

/* A file input draws its own button out of browser chrome, and it is the one
   control on the site that would otherwise look like it came from somewhere
   else. ::file-selector-button restyles it in place. */
.field[type="file"] { padding: 7px 11px; cursor: pointer; }
.field[type="file"]::file-selector-button {
  font: inherit; font-weight: 500; font-size: 13px; cursor: pointer;
  margin: 0 11px 0 0; padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink);
}
.field[type="file"]:hover::file-selector-button {
  border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink);
}
.field-sm { max-width: 140px; }
.field-xs { max-width: 122px; }

/* ------------------------------------------------------------------ flash */

.flash-shell { padding-top: 18px; }
.flash {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 15px; border-radius: var(--radius); font-size: 13.5px;
  border: 1px solid var(--ok-line); background: var(--ok-soft); color: var(--ok-ink);
  box-shadow: var(--shadow-sm);
}
.flash + .flash { margin-top: 8px; }
.flash-ok .gl { color: var(--ok); }
.flash-bad { border-color: var(--bad-line); background: var(--bad-soft); color: var(--bad-ink); }
.flash-bad .gl { color: var(--bad); }

/* ------------------------------------------------------------- chips etc. */

.chip {
  display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 100%;
  padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 500; white-space: nowrap;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink-2);
}
.chip .gl { color: var(--muted); font-size: 12px; }
.chip-time { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink); }
.chip-time .gl { color: var(--brand); }
.chip-warn { border-color: var(--warn-line); background: var(--warn-soft); color: var(--warn-ink); }
.chip-warn .gl { color: var(--warn); }
.chip-action { cursor: pointer; }
.chip-action:hover { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink); }
.chip-action:hover .gl { color: var(--brand); }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 500; white-space: nowrap;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink-2);
}
.badge .dot {
  width: 7px; height: 7px; border-radius: 999px; background: currentColor; flex: none;
  box-shadow: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 18%, transparent);
}
.badge-todo { border-color: var(--line-2); background: var(--surface-2); color: var(--muted); }
.badge-started { border-color: var(--warn-line); background: var(--warn-soft); color: var(--warn-ink); }
.badge-done { border-color: var(--ok-line); background: var(--ok-soft); color: var(--ok-ink); }
.badge-archived { border-color: var(--line-2); background: var(--surface-3); color: var(--muted); }
.badge-template { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink); }

.progress { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; }
.progress-track {
  display: block; width: 92px; height: 8px; flex: none;
  border-radius: 999px; background: var(--surface-3);
  border: 1px solid var(--line); overflow: hidden;
}
.progress-fill {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--brand), var(--brand-lift));
  transition: width .22s ease;
}
.progress-num {
  font-family: var(--display); font-size: 12.5px; font-weight: 600; color: var(--ink-2);
}

/* --------------------------------------------------------------- switches */

/* A switch, never a checkbox. Its form is display:contents so it lays out as
   though the button were a direct child of the row. */
.checkform { display: contents; }
.switch {
  position: relative; flex: none; cursor: pointer;
  width: 42px; height: 24px; padding: 0; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface-3);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .06);
}
.switch .knob {
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line-2);
  box-shadow: var(--shadow-sm);
  transition: transform .16s cubic-bezier(.3, 1.4, .5, 1);
}
.switch:hover { border-color: var(--brand); }
.switch.on { background: var(--ok); border-color: var(--ok); }
.switch.on { background: linear-gradient(135deg, var(--ok), color-mix(in srgb, var(--ok) 70%, var(--brand-lift))); }
.switch.on .knob { transform: translateX(18px); border-color: var(--ok); }
.switch.on:hover { border-color: var(--ok-ink); }

/* ------------------------------------------------------------------ split */

.split {
  display: grid; gap: var(--gap);
  grid-template-columns: minmax(0, 2.05fr) minmax(0, 1fr);
  align-items: start;
}
.split-main { min-width: 0; }
.split-rail { min-width: 0; display: flex; flex-direction: column; gap: var(--gap); }
.split-rail .panel + .panel { margin-top: 0; }

.railrows { border-top: 0; }
.railrow {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 15px; border-bottom: 1px solid var(--line);
}
.railrow:last-child { border-bottom: 0; }
.railrow::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--brand); opacity: 0;
}
.railrow:hover { background: var(--surface-2); }
.railrow:hover::before { opacity: 1; }
.railrow-main { min-width: 0; display: flex; flex-direction: column; }
.railrow-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.railrow-main:hover .railrow-name { color: var(--brand-ink); }
.railrow-sub { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* ----------------------------------------------------------- run + groups */

/* Cards in a row are EVEN: same top, same height, so the add-item row lines up
   across the bottom of every group instead of stepping down the page.

   align-items: stretch plus a flex column inside is what does it. The two traps
   that made them uneven, both paid for:
     - `.panel + .panel` adds a top margin, and grid children are siblings, so
       every card except the FIRST was pushed down by one gap. That is why the
       first one looked taller.
     - align-items: start sizes every card to its own content, so four groups
       with different item counts ended at four different heights. */
.rungrid, .groupgrid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  align-items: stretch;
}
.rungrid > .panel + .panel, .groupgrid > .panel + .panel { margin-top: 0; }
.groupgrid > .panel, .rungrid > .rungroup {
  display: flex; flex-direction: column;
}
.groupgrid > .panel > .items, .rungrid > .rungroup > .items { flex: 1 0 auto; }
.rungroup {
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
  background: var(--surface); box-shadow: var(--shadow-sm);
}
/* The footer of a stretched card sits at the bottom of it, not floating in the
   middle with empty ground underneath. */
.groupgrid > .panel > .panel-foot { margin-top: auto; }
.rungroup:hover { border-color: var(--line-2); }
.rungroup h3 {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 13px; font-size: 13px;
  background: var(--surface-2); background-image: var(--sheen);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.rungroup h3 .gl { color: var(--brand); }
.runcount {
  margin-left: auto; font-family: var(--display); font-size: 12px; color: var(--muted);
}

.runbar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 14px 17px; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); background-image: var(--sheen);
  box-shadow: var(--shadow-sm);
}
.runbar .progress-track { width: 230px; height: 10px; }
.runbar-copy { font-size: 13.5px; color: var(--ink-2); }
.runbar-note {
  display: flex; align-items: center; gap: 9px; margin-left: auto;
  color: var(--muted); font-size: 12.5px; min-width: 0;
}
.runbar-note .gl { color: var(--brand); }
.runbar-note span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.items { border-top: 0; }
/* One line per item. The name wraps inside its own column if it has to, which
   is text and allowed; the chips and the two tools sit in a block that wraps
   inside itself rather than pushing the row off the side of the page. */
.item {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 13px; border-bottom: 1px solid var(--line);
  min-width: 0;
}
/* The chips shrink before the name does, and they truncate the same way, so a
   long amount cannot push the name into an ellipsis on its own. */
.item-meta .chip { flex: 0 1 auto; overflow: hidden; }
.item-meta .chip span { overflow: hidden; text-overflow: ellipsis; }
.item:last-child { border-bottom: 0; }
.item:hover { background: var(--surface-2); }
/* An item name is ONE line. It gets the whole of the room the chips and the
   tools do not take, and anything past that truncates with the full text on the
   title attribute rather than wrapping the row to two lines. */
.item-name {
  min-width: 0; flex: 1 1 96px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.item-done .item-name { color: var(--muted); text-decoration: line-through; }
.item-empty { color: var(--muted); font-size: 13px; font-style: italic; }
.item-meta {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  justify-content: flex-end; margin-left: auto; min-width: 0;
}
.item-tools { display: flex; align-items: center; gap: 2px; flex: none; }
.item-order { display: flex; align-items: center; gap: 2px; flex: none; margin-left: auto; }

.item-edit {
  order: 99; flex: 1 0 100%;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 0 3px;
}
.item-edit .field { flex: 1 1 160px; width: auto; }

.additem, .group-rename { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.group-rename {
  padding: 11px 13px; border-bottom: 1px solid var(--line); background: var(--brand-soft);
}
.additem .field { flex: 1 1 150px; width: auto; }
.group-rename .field { flex: 1 1 160px; width: auto; }

/* ------------------------------------------------------------------- tabs */

/* A short, FIXED set of primary tabs stays visible at every width. The room is
   bought with tighter padding and a dropped icon, never with a second row and
   never with a sideways scroller. */
.tabs { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; margin-bottom: 16px; }
.tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 999px; white-space: nowrap;
  font-size: 13.5px; font-weight: 500; color: var(--ink-2);
  border: 1px solid var(--line-2); background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.tab .gl { color: var(--muted); }
.tab:hover { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink); }
.tab:hover .gl { color: var(--brand); }
.tab.current {
  background: linear-gradient(135deg, var(--brand), var(--brand-lift));
  border-color: var(--brand); color: var(--on-brand); box-shadow: var(--shadow);
}
.tab.current .gl, .tab.current:hover .gl { color: var(--on-brand); opacity: .82; }
.tab.current:hover {
  background: linear-gradient(135deg, var(--brand-ink), var(--brand));
  border-color: var(--brand-ink); color: var(--on-brand);
}
.tab-count {
  font-family: var(--display); font-size: 12px; font-weight: 600;
  padding: 0 6px; border-radius: 999px;
  background: var(--surface-3); color: var(--ink-2);
}
.tab.current .tab-count { background: rgba(255, 255, 255, .24); color: var(--on-brand); }

/* ----------------------------------------------------------------- tables */

.panel-flush .table { margin: 0; }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
  text-align: left; font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
  padding: 10px 15px; background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.table td { padding: 10px 15px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tbody tr { position: relative; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }
.table tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--brand); }
.table .row-warn td { background: var(--warn-soft); }
.table .right { text-align: right; }
.table .num { white-space: nowrap; }

.cell-main { display: flex; align-items: center; gap: 11px; min-width: 0; }
.cell-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none; border-radius: 10px;
  background: var(--brand-soft); border: 1px solid var(--brand-line); color: var(--brand);
}
.cell-copy { min-width: 0; display: flex; flex-direction: column; }
.cell-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell-main:hover .cell-name { color: var(--brand-ink); }
.cell-sub {
  color: var(--muted); font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 30ch;
}
.rowtools { display: inline-flex; align-items: center; gap: 3px; justify-content: flex-end; }
.rowtools form { display: contents; }

/* --------------------------------------------------------------- calendar */

.cal {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); overflow: hidden; box-shadow: var(--shadow-sm);
}
.cal-grid { display: block; }
.cal-head, .cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-head {
  background: var(--surface-2); background-image: var(--sheen);
  border-bottom: 1px solid var(--line);
}
.cal-dow {
  padding: 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap; text-align: center;
}
.cal-week + .cal-week { border-top: 1px solid var(--line); }
.cal-cell {
  min-width: 0; min-height: 108px; padding: 6px 7px 8px;
  border-left: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 4px;
}
.cal-cell:first-child { border-left: 0; }
.cal-cell:hover { background: var(--surface-2); }
.cal-out { background: var(--ground-2); }
.cal-out .cal-num { color: var(--muted); opacity: .55; }
.cal-past .cal-num { color: var(--muted); }
.cal-today { background: var(--brand-soft); }
.cal-today .cal-num {
  color: var(--on-brand);
  background: linear-gradient(135deg, var(--brand), var(--brand-lift));
  border-color: var(--brand);
  box-shadow: var(--shadow-sm);
}

.cal-top { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.cal-num {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; height: 24px; padding: 0 6px; border-radius: 8px;
  font-family: var(--display); font-size: 12.5px; font-weight: 600;
  border: 1px solid transparent;
}
.cal-add {
  display: inline-flex; align-items: center; justify-content: center;
  width: 23px; height: 23px; border-radius: 8px; flex: none;
  border: 1px solid transparent; color: var(--muted); opacity: 0;
}
.cal-cell:hover .cal-add, .cal-add:focus-visible { opacity: 1; }
.cal-add:hover { border-color: var(--brand-line); background: var(--surface); color: var(--brand); }

.cal-chips { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.calchip {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  padding: 3px 7px; border-radius: 8px; font-size: 11.5px; white-space: nowrap;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
  box-shadow: var(--shadow-sm);
}
.calchip:hover { border-color: var(--brand); color: var(--brand-ink); }
.calchip .dot { width: 6px; height: 6px; border-radius: 999px; flex: none; background: var(--muted); }
.calchip-todo .dot { background: var(--muted); }
.calchip-started .dot { background: var(--warn); }
.calchip-done .dot { background: var(--ok); }
.calchip-time { font-family: var(--display); font-weight: 600; flex: none; }
.calchip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* The legend lives INSIDE the calendar card. As its own section it was a thin
   strip of writing with a band of empty page around it. */
.cal-legend {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 11px 15px; border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: 12.5px; color: var(--muted);
}
.legend-item { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.legend-hint { margin-left: auto; }
.legend-hint .gl { color: var(--brand); }

/* A short explainer column. Medallion LEFT of its copy, like every other card
   in the app. */
.steps { display: flex; flex-direction: column; gap: 15px; }
.step { display: flex; align-items: flex-start; gap: 13px; min-width: 0; }
.step-copy { min-width: 0; display: flex; flex-direction: column; }
.step-name { font-weight: 600; font-size: 13.5px; }
.step-sub { color: var(--muted); font-size: 12.5px; margin-top: 2px; }

/* Templates sit two up in the main column, next to the explainer rail. */
.tplgrid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  align-items: stretch;
}
.tplgrid > .panel + .panel { margin-top: 0; }
.tplgrid > .panel { display: flex; flex-direction: column; }
.tplgrid > .panel > .items { flex: 1 0 auto; }
.tplgrid > .panel > .panel-foot { margin-top: auto; }

/* Set the date and go. The date field takes the room, the time is optional and
   narrow, and the button never wraps. */
.useform { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.useform .field { flex: 1 1 130px; width: auto; }
.useform .field-xs { flex: 0 1 118px; }

/* ------------------------------------------------------------ empty state */

.emptystate { display: flex; align-items: flex-start; gap: 17px; }
.emptystate-copy { min-width: 0; }
.emptystate-copy h3 { font-size: 17px; }
.emptystate-copy p { color: var(--muted); font-size: 13.5px; margin-top: 7px; }
.emptystate-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

.empty-line { display: flex; align-items: center; gap: 9px; color: var(--muted); font-size: 13px; }
.empty-line .gl { color: var(--brand); }
.empty-line a { color: var(--brand-ink); text-decoration: underline; text-underline-offset: 2px; }

/* The line that explains why the left column is showing a future session. */
.focus-note {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 15px; margin-bottom: var(--gap);
  border: 1px solid var(--warn-line); background: var(--warn-soft);
  border-radius: var(--radius); color: var(--warn-ink); font-size: 13px;
}
.focus-note .gl { color: var(--warn); }

/* A field beside the sentence that explains it, rather than a narrow panel with
   half the page empty to the right of it. */
.fieldrow-wide { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); align-items: end; }
.fieldnote {
  display: flex; align-items: flex-start; gap: 9px;
  color: var(--muted); font-size: 12.5px; padding-bottom: 10px;
}
.fieldnote .gl { color: var(--brand); margin-top: 2px; }

/* ----------------------------------------------------------- header search */

/* What used to be a second New List button. Every page carries its own, so the
   bar holds the one thing no page can do for itself. */
.navsearch { position: relative; display: flex; align-items: center; width: 270px; max-width: 100%; }
.navsearch > .gl { position: absolute; left: 12px; color: var(--muted); pointer-events: none; }
.navsearch-field {
  width: 100%; font: inherit; font-size: 14px; color: var(--ink);
  padding: 9px 42px 9px 35px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface-2);
  box-shadow: var(--shadow-sm);
  -webkit-appearance: none; appearance: none;
}
.navsearch-field::placeholder { color: var(--muted); opacity: .85; }
.navsearch-field::-webkit-search-cancel-button { display: none; }
.navsearch:hover .navsearch-field { border-color: var(--brand-line); background: var(--surface); }
.navsearch-field:focus {
  border-color: var(--brand); background: var(--surface); outline: none; box-shadow: var(--ring);
}
.navsearch-go {
  position: absolute; right: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; cursor: pointer;
  border-radius: 999px; border: 1px solid transparent;
  background: transparent; color: var(--muted);
}
.navsearch-go:hover { border-color: var(--line-2); background: var(--surface-3); color: var(--brand); }

/* The phone form: the field would leave no room for the nav, so it collapses to
   the icon, which opens the search page and its full width field. */
.navsearch-link {
  display: none; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 11px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--muted);
  box-shadow: var(--shadow-sm);
}
.navsearch-link:hover { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand); }

/* The search page's own field. Hidden wherever the header still has one, so the
   two are never both on screen. */
.pagesearch { position: relative; display: none; align-items: center; width: 100%; margin-bottom: var(--gap); }
.pagesearch > .gl { position: absolute; left: 12px; color: var(--muted); pointer-events: none; }
.pagesearch:hover .navsearch-field { border-color: var(--brand-line); }

/* ------------------------------------------------------------ search hits */

.hits { border-top: 0; }
.hit {
  display: flex; align-items: center; gap: 11px; flex-wrap: wrap;
  padding: 9px 15px; border-bottom: 1px solid var(--line); min-width: 0;
}
.hit:last-child { border-bottom: 0; }
.hit:hover { background: var(--surface-2); }
.hit-main { min-width: 0; flex: 1 1 140px; display: flex; flex-direction: column; }
.hit-name {
  font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hit-main:hover .hit-name { color: var(--brand-ink); }
.hit-where {
  color: var(--muted); font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hit-done .hit-name { color: var(--muted); text-decoration: line-through; }

/* ----------------------------------------------------------------- footer */

.site-footer { margin-top: 30px; }

/* No BORDER at the top: the light page giving way to a dark footer IS the
   separator, and a rule on top of a colour change is its own defect. The brand
   edge below is a painted band, not a hairline.

   FLAT, both of them. The first pass had a soft radial glow behind the top left
   and an edge that faded out to the right, and a gradient that dies into its
   own background is the thing that reads as unfinished rather than as depth. A
   solid band across the full width and one solid ground underneath it. */
.footer-links {
  position: relative;
  background: var(--strip-2); color: var(--strip-ink);
}
.footer-links::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--brand);
}

.foot-grid {
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 28px; padding: 32px 24px;
}
.foot-grid h3 {
  font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--strip-ink-2); margin-bottom: 12px; font-weight: 600;
}
.foot-grid nav { display: flex; flex-direction: column; align-items: flex-start; gap: 7px; }
/* FOOTER links: colour change only. Never a border, never a box. */
.foot-grid nav a, .legal-links a {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 13.5px; color: var(--strip-ink); white-space: nowrap;
}
.foot-grid nav a .gl, .legal-links a .gl { color: var(--strip-ink-2); }
.foot-grid nav a:hover, .legal-links a:hover { color: var(--strip-hi); }
.foot-grid nav a:hover .gl, .legal-links a:hover .gl { color: var(--strip-accent); }

.foot-brand { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.foot-tag {
  font-family: var(--display); font-size: 15px; color: var(--strip-ink);
  margin-top: 10px; letter-spacing: -0.01em;
}
.fnote {
  display: flex; align-items: flex-start; gap: 11px;
  font-size: 13px; color: var(--strip-ink-2); margin-top: 14px; max-width: 46ch;
}
/* A medallion, LEFT of its copy like every other one in the app. The ground is
   dark here, which is the one case that does not need a border, but it keeps
   one so the shape reads. Flat fill, no tint fading into the panel. */
.foot-medallion {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none; border-radius: 11px;
  background: var(--strip);
  border: 1px solid var(--strip-line);
  color: var(--strip-accent);
}

.footer-legal { background: var(--strip); border-top: 1px solid var(--strip-line); }
.legal-grid {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 15px 24px;
}
.footmark {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--display); font-size: 15.5px; font-weight: 600; color: var(--strip-hi);
  white-space: nowrap; letter-spacing: -0.01em;
}
.footmark .gl { color: var(--strip-accent); }
.footmark:hover { color: var(--strip-accent); }
.footmark-lg { font-size: 23px; letter-spacing: -0.02em; }
.footmark-lg .gl { width: 1.3em; height: 1.3em; }

.legal-links { display: flex; align-items: center; gap: 20px; margin-right: auto; }
.buildchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: 999px; white-space: nowrap;
  font-family: var(--display); font-size: 11.5px; font-weight: 500;
  border: 1px solid var(--strip-line); background: var(--strip-2); color: var(--strip-ink-2);
}
.buildchip .gl { color: var(--strip-ink-2); }

/* ---------------------------------------------------------------- tooltip */

/* A child of <body>, position: fixed, so nothing can clip it. An ::after on the
   element would be cut off by the first card with overflow: hidden, which is
   most of them. */
.tip {
  position: fixed; z-index: 80; pointer-events: none;
  max-width: 280px; padding: 7px 11px; border-radius: 8px;
  font-size: 12.5px; line-height: 1.35;
  background: var(--strip); color: var(--strip-hi);
  border: 1px solid var(--strip-line);
  box-shadow: var(--shadow-lg);
}
.tip[hidden] { display: none !important; }

/* ------------------------------------------------------- right click menu */

/* position: fixed and a child of body, so it is never clipped by the calendar
   card's overflow: hidden. A menu cut in half by the thing it belongs to is the
   whole failure this avoids. */
.ctxmenu {
  position: fixed; z-index: 70; min-width: 232px;
  display: flex; flex-direction: column; padding: 5px;
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.ctxmenu[hidden] { display: none !important; }
.ctxitem {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border-radius: 8px; white-space: nowrap;
  font: inherit; font-size: 13.5px; text-align: left; cursor: pointer;
  border: 1px solid transparent; background: transparent; color: var(--ink);
}
.ctxitem .gl { color: var(--muted); }
.ctxitem:hover { border-color: var(--line-2); background: var(--surface-2); color: var(--brand-ink); }
.ctxitem:hover .gl { color: var(--brand); }

/* ------------------------------------------------------------------ modal */

/* Never alert/confirm/prompt. A styled dialog, 20px title, and both axes
   pinned: once one axis is non-visible CSS computes the other as auto, which is
   exactly how a dialog ends up scrolling sideways. */
/* Closed by default, opened by the script OR by :target. The anchor fallback is
   what keeps the form reachable with the script gone, which matters when the
   form is the only way to add a group. */
.modal-open { overflow: hidden; }
.modal-wrap {
  position: fixed; inset: 0; z-index: 60;
  display: none; align-items: center; justify-content: center; padding: 20px;
}
.modal-wrap.is-open, .modal-wrap:target { display: flex; }
.modal-scrim { position: absolute; inset: 0; background: rgba(12, 10, 9, .6); backdrop-filter: blur(2px); }
.modal {
  position: relative; width: 100%; max-width: 460px;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-head {
  padding: 17px 21px; border-bottom: 1px solid var(--line);
  background: var(--surface-2); background-image: var(--sheen);
}
.modal-head h2 { font-size: 20px; }
.modal-sub { color: var(--muted); font-size: 13px; margin-top: 5px; }
.modal-body { padding: 19px 21px; overflow-x: hidden; overflow-wrap: anywhere; }
.modal-body input, .modal-body textarea { min-width: 0; max-width: 100%; }
.modal-copy { color: var(--ink-2); font-size: 14px; }
.modal-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 14px 21px; border-top: 1px solid var(--line); background: var(--surface-2);
}

/* Five controls in a group header have to fit a 320px grid column, so they are
   smaller there than anywhere else. The phone override above gives them back
   their full size, because there the groups are one per row. */
.group .panel-tools .iconbtn { width: 27px; height: 27px; }
.group .panel-tools .switch { width: 37px; height: 22px; }
.group .panel-tools .switch .knob { width: 16px; height: 16px; }
.group .panel-tools .switch.on .knob { transform: translateX(15px); }

/* ------------------------------------------------------------ responsive */

@media (max-width: 1180px) {
  .split { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
  .stat-num { font-size: 24px; }
  .navsearch { width: 215px; }
}

@media (max-width: 980px) {
  .foot-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot-brand { grid-column: 1 / -1; }
  .split { grid-template-columns: minmax(0, 1fr); }
  .statgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nav-grid { grid-template-columns: auto 1fr auto; }
  .mainnav { justify-self: end; }
  .navsearch { width: 185px; }
  .utility-facts .ufact:first-child { display: none; }
  .utility-facts .ufact:last-child { display: inline-flex; }
}

@media (max-width: 860px) {
  /* Tables stack instead of scrolling sideways. */
  .table thead { display: none; }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table tr { border-bottom: 1px solid var(--line); padding: 7px 0; }
  .table tbody tr:last-child { border-bottom: 0; }
  .table tbody tr:hover td:first-child { box-shadow: none; }
  .table td { border-bottom: 0; padding: 5px 15px; }
  .table td[data-label="List"] { padding-top: 10px; }
  .table td:not([data-label="List"])::before {
    content: attr(data-label) "  ";
    display: inline-block; min-width: 78px;
    font-size: 11.5px; font-weight: 600; letter-spacing: .05em;
    text-transform: uppercase; color: var(--muted);
  }
  .table .right { text-align: left; }
  .rowtools { justify-content: flex-start; }
}

@media (max-width: 900px) {
  .navlink span:not(.sr) { display: none; }
  .navlink { padding: 9px 11px; }
  .navlink .gl { font-size: 17px; }
}

@media (max-width: 760px) {
  .shell { padding: 0 16px; }
  .foot-grid, .legal-grid { padding-left: 16px; padding-right: 16px; }
  .nav-grid { min-height: 58px; }
  .cal-cell { min-height: 64px; padding: 4px; }
  .calchip-time, .calchip-name { display: none; }
  .cal-chips { flex-direction: row; flex-wrap: wrap; gap: 3px; }
  .calchip { padding: 3px; border-radius: 999px; }
  .cal-add { opacity: 1; }
  .foot-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; padding: 26px 16px; }
  .legal-links { margin-right: 0; }
  .runbar-note { margin-left: 0; }
  .fieldrow, .fieldrow-wide { grid-template-columns: minmax(0, 1fr); }
  .fieldnote { padding-bottom: 0; }
  .pagehead h1 { font-size: 25px; }
}

@media (max-width: 620px) {
  .tabs { gap: 4px; }
  .tab { padding: 8px 11px; font-size: 13px; gap: 5px; }
  .tab .gl { display: none; }
}

@media (max-width: 560px) {
  /* The search field would leave no room for the nav, so it becomes the icon
     beside it, which opens the search page and its full width field. */
  .navsearch { display: none; }
  .navsearch-link { display: inline-flex; }
  .pagesearch { display: flex; }
  /* The utility strip now carries an identity, three links, Sign Out and the
     theme toggle, and that does not fit a 375px bar. The three links are the
     ones to drop: every one of them is in the footer, in full, with its icon.
     What stays is what has nowhere else to be. */
  .utility-nav { display: none; }
  .pagesearch .navsearch-field { padding: 12px 46px 12px 38px; font-size: 15px; }
  .pagesearch .navsearch-go { width: 34px; height: 34px; right: 5px; }
  .themetoggle .themelabel { display: none; }
  /* The whole control is the tap target, so it gets thumb SIZE, both ways, even
     with the word taken out of it. Height alone left a 22px wide button. */
  .themetoggle { padding: 8px 10px; min-height: 38px; min-width: 38px; justify-content: center; }
  .wordmark { font-size: 18px; }
  /* A switch is 24px by design, so the ROW is the tap target, and every icon
     control grows to something a thumb can actually hit. */
  .item { padding: 10px 13px; }
  .switch { width: 46px; height: 26px; }
  .switch .knob { width: 20px; height: 20px; }
  .switch.on .knob { transform: translateX(20px); }
  .iconbtn { width: 36px; height: 36px; }
  .panel-tools { min-height: 38px; }
  /* The group header shrinks its controls to fit a 320px column on a desktop
     grid. On a phone the groups are one per row, so the room is there and the
     thumb gets its full size back. */
  .group .panel-tools .iconbtn { width: 36px; height: 36px; }
  .group .panel-tools .switch { width: 46px; height: 26px; }
  .group .panel-tools .switch .knob { width: 20px; height: 20px; }
  .group .panel-tools .switch.on .knob { transform: translateX(20px); }
  .field-sm, .field-xs { max-width: none; flex: 1 1 100px; }
}

@media (max-width: 470px) {
  /* Four nav icons, the mark and the search button do not all fit a 375px bar
     with the word on the mark. The pot keeps its place as the link home. */
  .nav-grid { gap: 8px; }
  .mainnav { gap: 2px; }
  .navlink { padding: 9px 8px; }
  .wordmark span:not(.sr) { display: none; }
  .wordmark { padding-right: 0; }
  .wordmark .gl { width: 1.6em; height: 1.6em; }
}

@media (max-width: 400px) {
  .statgrid { grid-template-columns: minmax(0, 1fr); }
}
