/* =====================================================================
   MyAnything — UI styles.

   No fonts, images or stylesheets are loaded from anywhere: the interface
   works with the network unplugged, forever. Icons are inline SVG defined
   once in index.html and referenced with <use>, for the same reason — no
   icon font, no sprite file, nothing fetched. Colours are defined once as
   tokens below and used by role everywhere else, so both themes swap in
   one place.

   The chrome follows the logo's cyan and blue, with violet used sparingly. Map marks keep their own
   accessible pair because the basemap is light in both themes.
   ===================================================================== */

:root {
  color-scheme: light;

  /* The shell is a pale blue frame in light mode. */
  --shell:        #eaf3ff;
  --side-ink:     #405674;
  --side-ink-hi:  #203a5d;
  --side-head:    #596f8d;
  --side-accent:  #386caa;
  --side-hover:   rgba(70, 119, 177, 0.08);
  --side-active:  #d4e7fb;
  --side-rule:    rgba(55, 94, 145, 0.17);
  --side-count:   rgba(55, 94, 145, 0.08);
  --side-count-active: rgba(55, 94, 145, 0.13);
  --side-badge-ink: #a13f55;

  --plane:        #fafcff;   /* the light panel: page background */
  --surface:      #ffffff;   /* cards, panels */
  --surface-2:    #f0f5fc;   /* table stripes, inset wells */
  --ink:          #111629;
  --ink-2:        #48536e;
  --ink-muted:    #5c6881;   /* >= 4.5:1 on all three light surfaces */
  --rule:         #e4ecf6;   /* hairline gridlines */
  --axis:         #c6d5e6;
  --border:       rgba(23, 43, 100, 0.10);

  --accent:       #2865aa;   /* chrome only */
  --accent-ink:   #ffffff;   /* text/icons on top of --accent */
  --accent-soft:  rgba(40, 101, 170, 0.11);

  /* Map marks are fixed across themes:
     OpenFreeMap's `liberty` basemap has no dark variant, so these render on a
     light surface in BOTH themes. Following the UI theme would validate them
     against a surface they never touch — the dark teal #25a7b8 measures 2.8:1
     on the light basemap, and its CVD separation from the cruise hue drops from
     19.5 to 8.2. So the map keeps one validated pair.
       #0a8f9e + #4a3aa7 on a light basemap: lightness band PASS, chroma PASS,
       CVD separation ΔE 19.5 (deutan) / 19.6 (tritan) PASS, normal-vision
       ΔE 23.7 PASS, contrast >= 3:1 PASS.
     Violet was chosen over orange and red — which also pass — because it is the
     only candidate that collides with no status colour, and its worst-case CVD
     separation is the most even across deutan/protan/tritan.
     Colour is never the only cue: flights are solid lines and filled dots,
     cruises are dashed lines and hollow rings, and the legend names both. */
  --map-flight:   #0a8f9e;
  --map-cruise:   #4a3aa7;
  /* The hero picks up the logo's cyan and blue without a heavy block of colour. */
  --hero:         linear-gradient(135deg, #c9f3f5, #c8ddf9);
  --hero-ink:     #173e61;
  --hero-label:   #355a77;

  /* Stat-tile washes. Decorative surfaces, cycled by position; they carry
     no meaning, so no value is ever encoded by which colour it landed on. */
  --tile-1:       #e2f6f5;  --tile-1-ink: #305762;
  --tile-2:       #e5f1ff;  --tile-2-ink: #35577c;
  --tile-3:       #edf2ff;  --tile-3-ink: #485c80;
  --tile-4:       #f2effa;  --tile-4-ink: #635a77;

  /* One day, one colour — the rail and pill edge of every dated list. A middle
     step of each tile hue, dark enough to read as a line on the panel and light
     enough to sit under a wash-filled pill. Decorative in exactly the sense the
     washes above are: the colour says which day a row belongs to and the
     heading above says the same thing in words, so nothing is encoded here that
     is not also written. Cycled off the DATE, never off a row's position, so
     two rows share a colour exactly when they share a day.
     Kept clear of --good/--warning/--serious/--critical in both themes: status
     is a saturated dot with a glyph and a word beside it, a day is a pale
     lozenge on a rail, and the two are never asked to be told apart. */
  --day-1:        #5b9daa;
  --day-2:        #638bc1;
  --day-3:        #8a91bc;
  --day-4:        #a788ad;

  --good:         #0ca30c;
  --warning:      #fab219;
  --serious:      #ec835a;
  --critical:     #d03b3b;

  --radius-panel: 22px;
  --radius:  16px;
  --radius-s: 10px;
  --pill: 999px;
  --shadow: 0 1px 2px rgba(11, 11, 11, 0.04), 0 10px 26px rgba(11, 11, 11, 0.05);
  --shadow-pop: 0 10px 34px rgba(42, 73, 117, 0.16);

  --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* Dark theme is selected, not an automatic flip: the panel darkens and the
   washes are re-stepped for a dark surface. */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --shell:       #2e4560;
    --side-ink:    #e4edf8;
    --side-ink-hi: #ffffff;
    --side-head:   #c7d6e9;
    --side-accent: #bce0ff;
    --side-hover:  rgba(226, 239, 255, 0.10);
    --side-active: rgba(194, 223, 255, 0.18);
    --side-rule:   rgba(226, 239, 255, 0.20);
    --side-count:  rgba(255, 255, 255, 0.10);
    --side-count-active: rgba(255, 255, 255, 0.16);
    --side-badge-ink: #ffd0d6;

    --plane:       #293a50;
    --surface:     #354a63;
    --surface-2:   #3e5470;
    --ink:         #f6f9ff;
    --ink-2:       #dce7f4;
    --ink-muted:   #c8d7e8;
    --rule:        #4a6179;
    --axis:        #69809a;
    --border:      rgba(255, 255, 255, 0.12);

    --accent:      #b6dcff;
    --accent-ink:  #193a5d;
    --accent-soft: rgba(182, 220, 255, 0.17);

    --hero:        linear-gradient(135deg, #a6e1e8, #b5d1ed);
    --hero-ink:    #173e61;
    --hero-label:  #315875;
    --tile-1:      #3b6570;  --tile-1-ink: #e2f6f7;
    --tile-2:      #3d5a78;  --tile-2-ink: #e3f1ff;
    --tile-3:      #4b5b79;  --tile-3-ink: #eaf0ff;
    --tile-4:      #5a556f;  --tile-4-ink: #f0eafa;

    /* The day hues lighten rather than darken here: the rail is drawn ON the
       panel, and the light-theme steps disappear into it. */
    --day-1:       #8fd3dd;
    --day-2:       #9bc6fa;
    --day-3:       #b8bee9;
    --day-4:       #ceb6d4;

    --shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 10px 26px rgba(0, 0, 0, 0.28);
    --shadow-pop: 0 10px 34px rgba(13, 34, 59, 0.24);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --shell:       #2e4560;
  --side-ink:    #e4edf8;
  --side-ink-hi: #ffffff;
  --side-head:   #c7d6e9;
  --side-accent: #bce0ff;
  --side-hover:  rgba(226, 239, 255, 0.10);
  --side-active: rgba(194, 223, 255, 0.18);
  --side-rule:   rgba(226, 239, 255, 0.20);
  --side-count:  rgba(255, 255, 255, 0.10);
  --side-count-active: rgba(255, 255, 255, 0.16);
  --side-badge-ink: #ffd0d6;

  --plane:       #293a50;
  --surface:     #354a63;
  --surface-2:   #3e5470;
  --ink:         #f6f9ff;
  --ink-2:       #dce7f4;
  --ink-muted:   #c8d7e8;
  --rule:        #4a6179;
  --axis:        #69809a;
  --border:      rgba(255, 255, 255, 0.12);

  --accent:      #b6dcff;
  --accent-ink:  #193a5d;
  --accent-soft: rgba(182, 220, 255, 0.17);

  --hero:        linear-gradient(135deg, #a6e1e8, #b5d1ed);
  --hero-ink:    #173e61;
  --hero-label:  #315875;
  --tile-1:      #3b6570;  --tile-1-ink: #e2f6f7;
  --tile-2:      #3d5a78;  --tile-2-ink: #e3f1ff;
  --tile-3:      #4b5b79;  --tile-3-ink: #eaf0ff;
  --tile-4:      #5a556f;  --tile-4-ink: #f0eafa;

  --day-1:       #8fd3dd;
  --day-2:       #9bc6fa;
  --day-3:       #b8bee9;
  --day-4:       #ceb6d4;

  --shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 10px 26px rgba(0, 0, 0, 0.28);
  --shadow-pop: 0 10px 34px rgba(13, 34, 59, 0.24);
}

* { box-sizing: border-box; }

/* Our own display rules must never out-rank hidden. */
[hidden] { display: none !important; }

html, body { min-height: 100%; }

body {
  margin: 0;
  background: var(--shell);
  color: var(--ink);
  font: 15px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--surface); padding: 10px 14px; border-radius: var(--radius-s);
}
.skip:focus { left: 8px; top: 8px; }

/* ---------------------------------------------------------------- shell */

/* The app is a light panel floating on the dark canvas. The window scrolls
   both the navigation and content together; only the search bar stays sticky. */
.shell {
  display: flex;
  gap: 12px;
  min-height: 100vh;
  padding: 12px;
  background: var(--shell);
}

.sidebar {
  width: 244px;
  flex: 0 0 244px;
  /* Keep the footer at the bottom of a short page while allowing the sidebar
     to grow and scroll with the window when its links need more room. */
  align-self: flex-start;
  min-height: calc(100vh - 24px);
  padding: 6px 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.brand { display: flex; align-items: center; gap: 11px; padding: 8px 8px 2px; }
.brand-mark {
  flex: none;
  width: 40px; height: 40px;
  display: block;
  /* the artwork is its own rounded tile, with its own colour: nothing is drawn behind it */
  filter: drop-shadow(0 4px 10px rgba(31, 78, 142, 0.23));
}
.brand-text { min-width: 0; }
.brand-name {
  display: block; color: var(--side-ink-hi);
  font-size: 17px; font-weight: 650; letter-spacing: -0.015em;
}
.brand-sub {
  display: block; font-size: 11.5px; color: var(--side-head); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.nav-group { display: flex; flex-direction: column; gap: 2px; }

.nav-head {
  margin: 0 0 6px 12px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--side-head);
}

.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px;
  border-radius: var(--pill);
  color: var(--side-ink);
  font-size: 14px;
  line-height: 1.2;
}
.nav-item .ico { flex: none; width: 17px; height: 17px; opacity: 0.85; }
.nav-item .txt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item:hover { background: var(--side-hover); text-decoration: none; color: var(--side-ink-hi); }
.nav-item.active {
  background: var(--side-active);
  color: var(--side-ink-hi);
  font-weight: 600;
}
.nav-item.active .ico { opacity: 1; color: var(--side-accent); }

.count {
  font-size: 11px; color: var(--side-head);
  font-variant-numeric: tabular-nums;
  background: var(--side-count);
  border-radius: var(--pill);
  padding: 1px 8px;
}
.nav-item.active .count { color: var(--side-ink-hi); background: var(--side-count-active); }

.nav-foot {
  margin-top: auto;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 6px 2px;
  border-top: 1px solid var(--side-rule);
}

.main-wrap {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--plane);
  border-radius: var(--radius-panel);
}

.topbar {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 26px;
  background: var(--plane);
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-panel) var(--radius-panel) 0 0;
  position: sticky; top: 0; z-index: 10;
}
.searchbox { flex: 1 1 auto; max-width: 520px; position: relative; }
.searchbox .search-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--ink-muted); pointer-events: none;
}
.searchbox input[type="search"] {
  padding: 9px 14px 9px 40px;
  border-radius: var(--pill);
  background: var(--surface);
}
.topbar-right { margin-left: auto; min-width: 0; }
.topbar-right #db-note {
  display: block; max-width: 42ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: right;
}

/* Full width: tables here run to nine columns and the room is wanted. Blocks
   that are read as prose rather than scanned set their own cap below. */
main { padding: 26px; width: 100%; }
main:focus { outline: none; }

/* ------------------------------------------------------------- typography */

h1 { font-size: 24px; font-weight: 650; letter-spacing: -0.02em; margin: 0 0 2px; }
h2 { font-size: 15px; font-weight: 600; margin: 0 0 10px; }
h3 { font-size: 13px; font-weight: 600; margin: 0 0 8px; color: var(--ink-2); }

.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
/* A flex basis, not max-content: some subtitles are a full sentence, and left
   to size themselves they blow the line width and wrap the actions off it. */
.page-head > :first-child { flex: 1 1 340px; min-width: 0; }
.page-head .spacer { flex: 1 1 auto; }
.subtitle { color: var(--ink-muted); font-size: 13px; max-width: 88ch; }
.muted { color: var(--ink-muted); }
.small { font-size: 12px; }
.mono { font-family: var(--mono); font-size: 12.5px; }

/* ------------------------------------------------------------------ cards */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
  box-shadow: var(--shadow);
}

.grid { display: grid; gap: 14px; }
/* Genuinely two columns: auto-fit would slip to three or four on a wide
   window, which leaves the last card stranded on a row of its own. */
.cols-2 { grid-template-columns: 1fr; }
@media (min-width: 900px) { .cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ------------------------------------------------------------- stat tiles */

/* Eight tiles land as two clean rows of four. auto-fit alone gives a ragged
   last row at most window widths, so the wide case is pinned to four. */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
@media (min-width: 1080px) { .kpi-row { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.tile {
  position: relative;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 16px 18px 18px;
  min-height: 116px;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow);
}
.tile .label { font-size: 12.5px; font-weight: 550; padding-right: 42px; }
.tile .value {
  font-size: 30px; font-weight: 650; letter-spacing: -0.025em;
  margin-top: auto; line-height: 1.1;      /* proportional figures, not tabular */
}
.tile .unit { font-size: 13px; font-weight: 500; opacity: 0.72; margin-left: 4px; }

/* The washes cycle by position and mean nothing; the label says what it is. */
.tile:nth-child(4n+1) { background: var(--tile-1); color: var(--tile-1-ink); }
.tile:nth-child(4n+2) { background: var(--tile-2); color: var(--tile-2-ink); }
.tile:nth-child(4n+3) { background: var(--tile-3); color: var(--tile-3-ink); }
.tile:nth-child(4n)   { background: var(--tile-4); color: var(--tile-4-ink); }
.tile .value { color: var(--ink); }

/* Exactly one hero per view — the soft cyan-blue gradient reads as the headline
   rather than as a fifth wash. */
.tile.hero {
  background: var(--hero);
  color: var(--hero-label);
  border-color: transparent;
}
.tile.hero .value { font-size: 48px; color: var(--hero-ink); }
.tile.hero .label { color: var(--hero-label); }

.tile .tile-ico {
  position: absolute; top: 14px; right: 14px;
  width: 34px; height: 34px; border-radius: var(--pill);
  display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.55);
}
.tile.hero .tile-ico { background: rgba(31, 83, 133, 0.10); }
.tile .tile-ico svg { width: 17px; height: 17px; display: block; }
:root[data-theme="dark"] .tile .tile-ico { background: rgba(255, 255, 255, 0.08); }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .tile .tile-ico { background: rgba(255, 255, 255, 0.08); }
}

/* --------------------------------------------------------------- statuses */

.status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 550; color: var(--ink-2);
  white-space: nowrap;
  background: var(--surface-2);
  border-radius: var(--pill);
  padding: 3px 10px;
}
.status .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.status .glyph { font-size: 11px; line-height: 1; }   /* icon + label, never colour alone */
.s-good     .dot { background: var(--good); }
.s-warning  .dot { background: var(--warning); }
.s-serious  .dot { background: var(--serious); }
.s-critical .dot { background: var(--critical); }

/* Available to anything that needs to say in words what a mark says in pixels. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* =========================================================== the dayline ===
 *
 * Every dated list is drawn by this one component: a date heading, a coloured rail under it, and one pill per
 * row that says the time if anything knows it. The dashboard's expiries, the latest flights and a record's
 * logged activity are all the same shape, so they are all the same widget.
 *
 * THE DATE IS THE HEADING. A thing with a date is something that happens on a day, and the date is a fact about
 * the row where a status word is a fact about today.
 *
 * THE PILL SAYS THE TIME, or nothing. `09:40` when a record states it; a blank lozenge when nothing does. It never
 * falls back to an implied hour.
 *
 * THE COLOUR IS THE DAY, and nothing else: four hues cycled off the date, so two rows match exactly when they
 * fall on one day. It is decorative, like the stat tiles' washes; status keeps its own palette.
 * ======================================================================= */
.dayline { display: flex; flex-direction: column; }

/* The day's colour, bound once per group and read by everything under it.
   Undated rows get the neutral fallback rather than a hue they did not earn. */
.dl-day {
  --day: var(--axis);
  --day-wash: var(--surface-2);
  --day-ink: var(--ink-2);
}
/* Interleave cyan, violet, blue and lilac so neighbouring days remain distinct
   even where the rail and the pill are small. */
.dl-day[data-hue="1"] { --day: var(--day-1); --day-wash: var(--tile-1); --day-ink: var(--tile-1-ink); }
.dl-day[data-hue="2"] { --day: var(--day-3); --day-wash: var(--tile-3); --day-ink: var(--tile-3-ink); }
.dl-day[data-hue="3"] { --day: var(--day-2); --day-wash: var(--tile-2); --day-ink: var(--tile-2-ink); }
.dl-day[data-hue="4"] { --day: var(--day-4); --day-wash: var(--tile-4); --day-ink: var(--tile-4-ink); }

.dl-head { display: flex; align-items: center; gap: 9px; padding: 15px 0 7px; }
.dl-day:first-child > .dl-head { padding-top: 1px; }
.dl-pip { flex: none; width: 9px; height: 9px; border-radius: var(--pill); background: var(--day); }
.dl-date {
  font-size: 14px; font-weight: 700; letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.dl-note {
  font-size: 12.5px; color: var(--ink-muted); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Carries the eye from the date across to the count, and marks how far the
   group reaches. Decorative, hence hidden from the accessibility tree. */
.dl-rule { flex: 1 1 auto; min-width: 10px; height: 1px; background: var(--rule); }
.dl-count { flex: none; font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }

.dl-list { list-style: none; margin: 0; padding: 0; }
.dl-row { display: flex; align-items: flex-start; gap: 10px; padding: 3px 0; position: relative; }

/*
 * The rail: the day's first pill to its last, unbroken.
 *
 * Drawn per item rather than once down the group, because the group's last item
 * is as tall as its own text and the line has to stop at that item's pill
 * rather than at the bottom of a two-line box. So every item draws a full-height
 * segment and they meet, including any sub-heading inside a day, which is an item
 * of the same list precisely so the line runs through it.
 *
 * The two ends are trimmed to their pill. A day that opens with a place heading
 * draws nothing beside it: there is no pill up there to run from. And a group
 * of one row ends up with both trims at once, so it gets no rail at all —
 * correctly, since a rail joins things to each other.
 */
.dl-row::before, .dl-place::before {
  content: ''; position: absolute; left: 28px; top: 0; bottom: 0;
  width: 2px; border-radius: 2px; background: var(--day); opacity: 0.5;
}
.dl-list > .dl-row:first-child::before,
.dl-list > .dl-place:first-child + .dl-row::before { top: 21px; }
.dl-list > .dl-place:first-child::before { content: none; }
.dl-list > :last-child::before { bottom: calc(100% - 21px); }

/* The pill's box is a fixed height whatever it holds, so a timed row and an
   untimed one sit on the same rail rather than stepping around it. */
.dl-mark {
  flex: none; width: 58px; height: 22px; margin-top: 7px;
  display: flex; align-items: center; justify-content: center;
  position: relative; z-index: 1;
}
.dl-pill {
  display: inline-flex; align-items: center; justify-content: center;
  height: 20px; max-width: 100%; padding: 0 8px; border-radius: var(--pill);
  background: var(--day-wash); color: var(--day-ink); border: 1px solid var(--day);
  font-size: 11.5px; font-weight: 650; line-height: 1; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* Nothing knows the time. The row is still marked on the rail — it just does
   not pretend to say when. */
.dl-pill.blank { height: 10px; width: 22px; padding: 0; background: var(--day); }

.dl-box {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 3px solid var(--day);
  border-radius: var(--radius-s);
}
/* Aligned to the title, not to the middle of the box: a row whose detail wraps
   to two lines would otherwise float its icon between them. Qualified by
   .dl-box because the base .rowico centres itself and is declared after this. */
.dl-box .dl-ico { flex: none; align-self: flex-start; color: var(--accent); margin-top: 2px; }
.dl-box .dl-ico svg { width: 16px; height: 16px; display: block; }
.dl-body { flex: 1 1 auto; min-width: 0; }
/* display:block matters: the title is often an <a>, and overflow/ellipsis are
   ignored on an inline box — without it a long title runs under the status. */
.dl-title {
  display: block; font-size: 13.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dl-verb { color: var(--ink-2); font-weight: 550; }
.dl-sub { font-size: 12px; color: var(--ink-muted); }
/* A row whose detail is the point of the row rather than a label for it — what
   was actually done to the plant, not which kind of thing it was. */
.dl-sub.lead { font-size: 12.5px; color: var(--ink-2); line-height: 1.45; }
.dl-right { flex: none; display: flex; align-items: center; gap: 8px; }
/* Controls inside a row stack on the pill's baseline rather than the title's. */
.dl-right .btn { padding: 5px 11px; font-size: 12px; }
.dl-right select { padding: 5px 8px; font-size: 12px; }

/* The landing half of a flight: the same number you already read on the
   departure line, so it steps back rather than repeating itself at full volume.
   The day's edge remains, or the column of coloured edges would break every time
   a flight lands and the list would read as two kinds of thing. */
.dl-row.quiet .dl-box {
  background: transparent; border-color: transparent; border-left-color: var(--day);
  /* Square: a 3px edge with nothing behind it draws its rounded corners as a
     stray bracket. */
  border-radius: 0;
}
.dl-row.quiet .dl-verb,
.dl-row.quiet .dl-title a,
.dl-row.quiet .dl-title { color: var(--ink-muted); font-weight: 500; }
/* Done, and kept: struck through but still there. */
.dl-row.done .dl-title a, .dl-row.done .dl-title { text-decoration: line-through; }
.dl-row.done .dl-title, .dl-row.done .dl-title a { color: var(--ink-muted); }
/* Still in the archive, no longer live — present but recessive. The title alone
   is struck through; the note underneath is why it is kept. */
.dl-row.retired .dl-title { text-decoration: line-through; }
.dl-row.retired .dl-title, .dl-row.retired .dl-sub { color: var(--ink-muted); }

/* The places one day happens in. A day that moves you has several, and that is
   the only grouping a day genuinely has. An item of the day's list, indented by
   padding rather than margin so the rail still measures from the list's edge
   and passes behind it. */
.dl-place {
  position: relative; padding: 7px 0 2px 71px;
  font-size: 12px; font-weight: 650; letter-spacing: 0.01em; color: var(--ink-2);
}

/* Days with nothing on them and a bed to sleep in, collapsed to one line.
   Indented to the rows' own column: a run of empty days is something the
   timeline says, not a heading over what follows. */
.dl-quiet {
  margin: 8px 0 2px 68px; padding: 8px 12px 8px 14px;
  border-left: 3px solid var(--axis); border-radius: var(--radius-s);
  background: var(--surface-2);
  font-size: 12.5px; color: var(--ink-muted);
}

/*
 * A stretch with nowhere to sleep. The one red thing on this timeline, and it
 * is drawn once per run however many days the run covers.
 */
.dl-gap {
  margin: 8px 0 2px 68px; padding: 9px 12px 9px 14px;
  border-left: 3px solid var(--critical); border-radius: var(--radius-s);
  background: var(--surface-2);
}
.dl-gap-title { font-size: 13.5px; font-weight: 650; color: var(--critical); }
.dl-gap-sub { font-size: 12.5px; color: var(--ink-muted); margin-top: 1px; }

/* Inline SVG at text size, wherever a row names what it is. NOT `.ico`, which
   the sidebar's own icons already wear on the dark canvas — one class cannot
   answer to two colour roles. */
.rowico { flex: none; color: var(--accent); align-self: center; }
.rowico svg { width: 15px; height: 15px; display: block; }

/* The stored columns of a record whose page is a dashboard. Present, one click
   away, and not in the way. */
details.fold > summary {
  cursor: pointer; font-weight: 600; font-size: 14px; color: var(--ink-2);
  list-style: none;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::before { content: '▸ '; color: var(--ink-muted); }
details.fold[open] > summary::before { content: '▾ '; }
details.fold[open] > summary { margin-bottom: 10px; }

.badge {
  display: inline-block; padding: 2px 9px; border-radius: var(--pill);
  font-size: 11px; font-weight: 550;
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--border);
}
.badge-ro { color: var(--critical); }
/* The read-only badge lives on the dark canvas, not on a card. */
.nav-foot .badge { background: var(--side-count); border-color: var(--side-rule); color: var(--side-badge-ink); }

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

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

table { border-collapse: collapse; width: 100%; font-size: 13.5px; }

th, td {
  text-align: left;
  padding: 11px 16px;
  border-bottom: 1px solid var(--rule);      /* hairline, solid, recessive */
  white-space: nowrap;
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
}
th {
  font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-muted); background: var(--surface-2);
  position: sticky; top: 0;
}
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
th .arrow { color: var(--accent); }
tbody tr:last-child td { border-bottom: none; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--surface-2); }
/* Still in the archive, no longer in the collection — present but recessive. */
tbody tr.retired td { color: var(--ink-muted); text-decoration: line-through; }
tbody tr.retired td:first-child { text-decoration: none; font-style: italic; }
/* The same "done, and kept" treatment outside a table: the title alone is struck through; the note underneath
   is why it was kept, and reading it back is the point. */
.attn-row.retired .attn-title { text-decoration: line-through; }
.attn-row.retired .attn-title,
.attn-row.retired .attn-sub { color: var(--ink-muted); }
td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* The summary row: a rule above it and a heavier weight, so it reads as a
   conclusion about the rows rather than one more of them. It is never
   clickable — there is no record behind a total. */
tfoot td {
  border-top: 2px solid var(--rule);
  font-weight: 650;
  background: var(--surface);
  white-space: nowrap;
}
tfoot td.total-label { color: var(--ink-muted); font-weight: 550; }
/* width:1% collapses a column to its content under auto table layout, so the
   spare width in a wide window lands on the text columns rather than pushing
   numbers away from the headers above them. */
th.num { text-align: right; }
th.num, td.num { width: 1%; white-space: nowrap; }

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

input, select, textarea, button { font: inherit; color: inherit; }

input[type="text"], input[type="search"], input[type="number"], select, textarea {
  width: 100%;
  padding: 9px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  outline: none;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
textarea { min-height: 72px; resize: vertical; }

.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12px; font-weight: 550; color: var(--ink-2); margin-bottom: 5px; }
.field .hint { font-size: 11px; color: var(--ink-muted); margin-top: 3px; }
.field.required label::after { content: " *"; color: var(--critical); }

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 18px; }
.form-grid .wide { grid-column: 1 / -1; }

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px;
  border-radius: var(--radius-s);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 13.5px; font-weight: 600;
  cursor: pointer;
}
.btn:hover { filter: brightness(1.08); text-decoration: none; }
.btn.secondary { background: var(--surface); color: var(--ink); border-color: var(--border); }
.btn.secondary:hover { background: var(--surface-2); filter: none; }
.btn.danger { background: var(--surface); color: var(--critical); border-color: var(--border); }
.btn.danger:hover { background: var(--surface-2); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.ghost-btn {
  background: none; border: 1px solid var(--border); border-radius: var(--pill);
  padding: 5px 12px; font-size: 12px; color: var(--ink-2); cursor: pointer;
}
.ghost-btn:hover { background: var(--surface-2); color: var(--ink); }
.ghost-btn.on { border-color: var(--accent); color: var(--ink); background: var(--accent-soft); }
/* In the sidebar the ghost button sits on the dark canvas. */
.nav-foot .ghost-btn { border-color: var(--side-rule); color: var(--side-ink); }
.nav-foot .ghost-btn:hover { background: var(--side-hover); color: var(--side-ink-hi); }

.btn-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 16px; }
.btn-row .spacer { flex: 1 1 auto; }

/* A list's filter + actions sit in a .btn-row in the page head. Its width is
   shrink-to-fit, so a width:100% input collapses the row onto one item and
   pushes the button to a second line — the filter gets a real width instead. */
.page-head .btn-row { flex-wrap: nowrap; }
.page-head .btn-row input[type="search"] { width: 260px; }

/* --------------------------------------------------------------- lists */

.attn-list { display: flex; flex-direction: column; }
.attn-row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
}
.attn-row:last-child { border-bottom: none; }
.attn-main { flex: 1 1 auto; min-width: 0; }
/* display:block matters: the title is an <a>, and overflow/ellipsis are
   ignored on an inline box — without it a long title runs under the date. */
.attn-title { display: block; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attn-sub { font-size: 12px; color: var(--ink-muted); }
.attn-when { text-align: right; font-size: 12px; white-space: nowrap; }
.attn-when .date { font-variant-numeric: tabular-nums; color: var(--ink-2); display: block; margin-bottom: 3px; }

.empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--ink-muted);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.empty p { margin: 0 0 12px; }

/* Capped: this is read line by line, and a 2000px line of notes is unreadable. */
.kv { display: grid; grid-template-columns: minmax(120px, 190px) minmax(0, 1fr);
      gap: 8px 16px; font-size: 13.5px; max-width: 1100px; }
.kv dt { color: var(--ink-muted); font-size: 12px; padding-top: 2px; }
.kv dd { margin: 0; word-break: break-word; }

/* Activity is a dayline too — one .dl-day per date logged. What kind of thing
   was done is a word, not a time, so it sits where a status pill would rather
   than in the time pill, which remains blank because no event records an hour. */
.dl-kind { font-size: 11px; padding: 1px 8px; }

.log-activity { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }

.chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--pill); font-size: 12px;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--ink-2);
}
.chip .rel { color: var(--ink-muted); }
.chip.broken { border-style: dashed; color: var(--critical); }

/* ------------------------------------------------------------------ map */

.map-card { padding: 10px 10px 6px; max-width: 1500px; }

/* MapLibre measures its container rather than growing to fit it, so the box
   needs a real height — a zero-height container gives a zero-sized canvas. */
.map-gl {
  position: relative;
  height: min(68vh, 620px);
  min-height: 340px;
  border-radius: var(--radius-s);
  overflow: hidden;
  background: var(--surface-2);
}

/* Shown when the library or the tile server cannot be reached — the one
   failure this interface can have that is not the archive's fault. */
.map-problem {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 6px; text-align: center; padding: 24px;
  background: var(--surface);
}
.map-problem p { margin: 0; max-width: 48ch; }
.map-problem-title { font-weight: 600; }

.map-legend { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; padding: 8px 10px 4px; font-size: 12px; color: var(--ink-muted); }

/* MapLibre's own chrome, dressed in this interface's tokens instead of its
   stock white — otherwise the popups and buttons read as a foreign widget. */
.maplibregl-popup-content {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-pop);
  padding: 10px 13px;
  font: 13px/1.45 var(--sans);
}
.maplibregl-popup-content .t-title { font-weight: 600; }
.maplibregl-popup-content .t-sub { color: var(--ink-muted); font-size: 12px; }
.maplibregl-popup-content a { display: inline-block; margin-top: 6px; font-size: 12.5px; }
.maplibregl-popup-close-button { color: var(--ink-muted); font-size: 17px; padding: 0 7px; }
.maplibregl-popup-close-button:hover { background: var(--surface-2); color: var(--ink); }
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--surface); }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--surface); }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--surface); }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--surface); }
.maplibregl-ctrl-group { border-radius: var(--radius-s); overflow: hidden; box-shadow: var(--shadow); }

/* ---------------------------------------------------------------- toast */

.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  z-index: 80;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-s);
  padding: 11px 18px; font-size: 13.5px;
  box-shadow: var(--shadow-pop);
  max-width: min(560px, 90vw);
}
.toast.bad { border-left-color: var(--critical); }

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

@media (max-width: 860px) {
  .shell { flex-direction: column; padding: 8px; gap: 8px; }
  /* The nav becomes a wrapped bar across the top, so it scrolls with the page
     rather than staying pinned — there is no room to pin it to. */
  .sidebar {
    width: auto; flex: none; min-height: 0;
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px;
    padding: 8px 10px;
  }
  .brand { padding: 4px 6px; }
  .nav-group { flex-direction: row; flex-wrap: wrap; gap: 4px; }
  .nav-head { display: none; }
  .nav-item { padding: 7px 11px; }
  .nav-foot { margin-top: 0; border-top: none; padding: 0 4px; }
  main, .topbar { padding-left: 16px; padding-right: 16px; }

  /* The rail narrows but remains: it is what makes a phone-width list readable
     as days rather than as one long run of rows. A blank pill shrinks to a
     dot's worth of width; a time pill keeps its digits at full size. */
  .dl-mark { width: 44px; }
  .dl-row::before, .dl-place::before { left: 21px; }
  .dl-place { padding-left: 57px; }
  .dl-quiet, .dl-gap { margin-left: 54px; }
  .dl-row { gap: 8px; }
  /* Status and controls drop under the text rather than squeezing it to a
     column of two words. */
  .dl-box { padding: 7px 10px; flex-wrap: wrap; }
  .dl-right { width: 100%; justify-content: flex-start; }
}

/* ---- a location's printed label -------------------------------------- */
.label-controls {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: 4px 18px; margin-bottom: 12px;
}
.label-controls .field { margin-bottom: 6px; }
.label-inline {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: var(--ink-2); margin-bottom: 6px;
}
.label-inline input { margin: 0; }
.label-stage {
  display: flex; justify-content: center;
  padding: 16px; border-radius: var(--radius-s);
  background: var(--surface-2); overflow: auto;
}
/* The preview is the printout: one canvas pixel is one printer dot, scaled up
   with no smoothing so the thresholded edges are the ones that will burn. */
.label-canvas {
  display: block; height: auto;
  image-rendering: pixelated; image-rendering: crisp-edges;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}
.label-card .mono { word-break: break-all; }

@media print {
  body { background: #fff; }
  .shell { display: block; padding: 0; min-height: 0; }
  .sidebar, .topbar, .btn-row, .toast { display: none !important; }
  .main-wrap { border-radius: 0; background: #fff; }
  main { padding: 0; }
  .card, .tile, .table-wrap { border-color: #999; box-shadow: none; }
  .tile { background: #fff !important; color: #000 !important; }
  /* A day's colour is decorative and the heading says the date in words, so
     the rail and the washes come off the page rather than printing as grey
     blocks. The pill keeps its outline, because it still carries the time. */
  .dl-box, .dl-quiet, .dl-gap { background: #fff !important; border-color: #999; }
  .dl-row::before, .dl-place::before, .dl-pip { display: none; }
  .dl-pill { background: #fff !important; color: #000 !important; border-color: #999; }
  .dl-pill.blank { visibility: hidden; }
}

/* =====================================================================
   Sign-in and account pages (MA-28). Plain pages with no sidebar: a card
   on the dark canvas, on the same tokens as the app.
   ===================================================================== */

input[type="email"], input[type="password"], input[type="tel"], input[type="url"], input[type="date"] {
  width: 100%;
  padding: 9px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  outline: none;
}
input[type="email"]:focus, input[type="password"]:focus, input[type="tel"]:focus, input[type="url"]:focus, input[type="date"]:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}

.auth-body { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: 20px; }
.auth-card {
  width: 100%; max-width: 440px;
  background: var(--surface); color: var(--ink);
  border-radius: var(--radius-panel); box-shadow: var(--shadow-pop);
  padding: 30px 30px 26px;
}
.auth-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.auth-brand .brand-name { color: var(--ink); font-size: 18px; }
.auth-brand .brand-sub { color: var(--ink-muted); font-size: 12px; }
.auth-card h1 { font-size: 21px; margin: 0 0 6px; }
.auth-card .lead { color: var(--ink-2); margin: 0 0 18px; }
.auth-card .btn { width: 100%; justify-content: center; }
.auth-card .btn-row { margin-top: 12px; }
.auth-links { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 16px; font-size: 13px; }
.legal-acceptance { margin: 12px 0 18px; font-size: 13px; line-height: 1.5; }
.legal-acceptance label { display: flex; align-items: flex-start; gap: 9px; }
.legal-acceptance input { flex: none; margin-top: 3px; }
.legal-document { max-width: 760px; width: 100%; margin: 24px auto; }
.legal-document h2 { margin-top: 24px; }
.legal-document p { line-height: 1.6; }
.auth-note {
  border-radius: var(--radius-s); padding: 10px 12px; margin: 0 0 16px; font-size: 13.5px;
  background: var(--accent-soft); color: var(--ink);
}
.auth-note.bad { background: rgba(208, 59, 59, 0.12); }
.auth-note.good { background: rgba(12, 163, 12, 0.12); }
.widget-holder { min-height: 70px; margin: 4px 0 14px; display: flex; justify-content: center; }
.codes { columns: 2; font-family: var(--mono); font-size: 14px; background: var(--surface-2); border-radius: var(--radius-s); padding: 12px 16px; margin: 10px 0; }
.codes div { break-inside: avoid; padding: 2px 0; }
.qr { display: block; margin: 10px auto; width: 188px; height: 188px; image-rendering: pixelated; background: #fff; padding: 8px; border-radius: var(--radius-s); }
.secret-key { font-family: var(--mono); word-break: break-all; background: var(--surface-2); padding: 8px 10px; border-radius: var(--radius-s); font-size: 13px; }

/* the account page, inside the app */
.settings-section { margin-bottom: 18px; }
.settings-section h2 { margin-top: 0; }
.settings-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 10px 0; border-top: 1px solid var(--rule); }
.settings-row:first-of-type { border-top: 0; }
.settings-row .what { min-width: 0; }
.settings-row .what .title { font-weight: 600; }
.settings-row .what .sub { color: var(--ink-muted); font-size: 12.5px; }
.pill-tag { display: inline-block; border-radius: var(--pill); padding: 1px 9px; font-size: 11.5px; background: var(--accent-soft); color: var(--ink); margin-left: 8px; }
.switch { display: inline-flex; align-items: center; gap: 8px; }
.switch input { width: 18px; height: 18px; accent-color: var(--accent); }

.nav-group[hidden] { display: none; }
.checks { display: flex; flex-direction: column; gap: 10px; margin: 10px 0; }
.check { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.check input { margin-top: 4px; }
.activity { list-style: none; margin: 8px 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.activity .when { display: inline-block; min-width: 11em; }
.small.bad { color: var(--bad, #b3261e); font-weight: 600; }
.token-value { display: block; padding: 10px; margin: 8px 0; word-break: break-all; background: var(--card-alt, rgba(127,127,127,.12)); border-radius: 6px; user-select: all; }

/* ---- scanning a place (MA-32) ---- */
.scan-thumbs { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }
.scan-thumb { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.scan-thumb img { width: 96px; height: 96px; object-fit: cover; border-radius: 8px; border: 1px solid var(--border); }
.reader-row { padding: 12px 0; border-top: 1px solid var(--border); }
.reader-row:first-of-type { border-top: 0; }

/* 2026 dashboard refresh: quiet gray canvas, white cards and small colour cues. */
:root {
  --shell: #f7f8fb;
  --plane: #f0f1f7;
  --surface-2: #f7f8fb;
  --ink: #252a3b;
  --ink-2: #576175;
  --ink-muted: #788398;
  --rule: #e9ebf1;
  --border: #e4e7ee;
  --side-ink: #9aa5b7;
  --side-ink-hi: #252a3b;
  --side-head: #8b96a9;
  --side-accent: #756de6;
  --side-hover: #f3f2ff;
  --side-active: #ffffff;
  --accent: #665bd7;
  --accent-soft: #ebe9ff;
  --hero: #ffffff;
  --hero-ink: #252a3b;
  --hero-label: #788398;
  --tile-1: #f0efff; --tile-1-ink: #756de6;
  --tile-2: #f9edfb; --tile-2-ink: #b367ce;
  --tile-3: #eaf8f1; --tile-3-ink: #29a96d;
  --tile-4: #eaf3ff; --tile-4-ink: #4e88da;
  --day-1: #7f80ef;
  --day-2: #538ee7;
  --day-3: #b978e5;
  --day-4: #df79b3;
  --radius: 24px;
  --shadow: 0 2px 12px rgba(35, 42, 68, 0.035);
  --shadow-pop: 0 16px 42px rgba(37, 42, 59, 0.13);
}

.rail-group-toggle { display: none; }
.rail-group-toggle { position: relative; }
.rail-lock-badge { position: absolute; right: 8px; bottom: 7px; width: 12px; height: 12px; color: var(--ink-muted); }
.rail-lock-badge svg { display: block; width: 100%; height: 100%; }
.topbar { gap: 24px; }
.top-links { display: flex; gap: clamp(15px, 2vw, 34px); align-items: center; white-space: nowrap; }
.top-links a { color: var(--ink-muted); font-size: 14px; font-weight: 550; }
.top-links a:hover, .top-links a.active { color: var(--ink); text-decoration: none; }
.top-links a.active { font-weight: 700; }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-actions .unlock-control { padding: 0; justify-content: flex-end; }
.topbar-actions .unlock-state { color: var(--ink-muted); white-space: nowrap; }
.topbar-actions .ghost-btn { padding: 7px 12px; border-radius: var(--pill); font-size: 12px; }
.account-shortcut { width: 42px; height: 42px; border-radius: 50%; flex: none; display: grid; place-items: center; background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.account-shortcut svg { width: 21px; height: 21px; }
.account-shortcut:hover { text-decoration: none; color: var(--accent); }

.dashboard-intro { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin: 12px 0 62px; }
.dashboard-eyebrow { color: var(--ink-muted); font-size: 15px; margin: 0 0 4px; }
.dashboard-intro h1 { font-size: clamp(30px, 3vw, 44px); letter-spacing: -0.045em; line-height: 1.1; font-weight: 650; margin: 0 0 14px; }
.dashboard-subtitle { color: var(--ink-muted); font-size: 15px; margin: 0; }
.dashboard-date { min-width: 210px; padding: 16px 22px; border-radius: 18px; background: var(--surface); box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 2px; }
.dashboard-date span { color: var(--ink-muted); font-size: 11px; letter-spacing: .08em; }
.dashboard-date strong { color: var(--ink); font-size: 20px; }
.dashboard-date::after { content: ''; height: 5px; margin-top: 11px; border-radius: 99px; background: linear-gradient(90deg, #7779ed, #c775db, #ee75b4); }
.dashboard-section-title { font-size: 20px; font-weight: 650; letter-spacing: -.025em; margin: 0 0 22px; }
.dashboard-section-title:not(:first-child) { margin-top: 36px; }

.kpi-row { gap: 18px; margin-bottom: 38px; }
.tile { background: var(--surface) !important; color: var(--ink-muted) !important; border: 1px solid var(--border); min-height: 158px; padding: 25px; border-radius: 26px; }
.tile .label { font-size: 13px; font-weight: 500; margin-top: 53px; padding: 0; }
.tile .value, .tile.hero .value { font-size: 28px; font-weight: 650; margin-top: 3px; color: var(--ink); }
.tile.hero .label { color: var(--ink-muted); }
.tile .tile-ico, .tile.hero .tile-ico { top: 22px; left: 22px; right: auto; width: 38px; height: 38px; }
.tile:nth-child(4n+1) .tile-ico { background: var(--tile-1); color: var(--tile-1-ink); }
.tile:nth-child(4n+2) .tile-ico { background: var(--tile-2); color: var(--tile-2-ink); }
.tile:nth-child(4n+3) .tile-ico { background: var(--tile-3); color: var(--tile-3-ink); }
.tile:nth-child(4n) .tile-ico { background: var(--tile-4); color: var(--tile-4-ink); }
.card { border-radius: 26px; padding: 28px 30px; }
.card h2 { font-size: 19px; letter-spacing: -.02em; }
.card a.small { padding: 7px 12px; border-radius: 8px; background: var(--surface-2); color: var(--ink-2); font-weight: 600; }
.card a.small:hover { background: var(--accent-soft); color: var(--accent); text-decoration: none; }
.grid { gap: 20px; }

@media (min-width: 861px) {
  .shell { gap: 0; padding: 0; }
  .sidebar { width: 102px; flex: 0 0 102px; min-height: 100vh; position: sticky; top: 0; z-index: 20; padding: 34px 16px 20px; align-items: center; gap: 0; background: var(--shell); border-right: 1px solid var(--border); }
  .brand { padding: 0 0 48px; }
  .brand-mark { width: 54px; height: 54px; filter: none; border-radius: 16px; }
  .brand-text { display: none; }
  .sidebar > .nav-group { width: 100%; position: relative; margin: 5px 0; }
  .dashboard-group .nav-item, .rail-group-toggle { width: 60px; height: 60px; padding: 0; margin: 0 auto; border: 0; border-radius: 18px; display: grid; place-items: center; background: transparent; color: var(--side-ink); cursor: pointer; }
  .dashboard-group .nav-item .ico, .rail-group-toggle .ico { width: 22px; height: 22px; }
  .dashboard-group .nav-item .txt, .dashboard-group .nav-item .count { display: none; }
  .dashboard-group .nav-item.active, .rail-group-toggle.active, .rail-group-toggle:hover, .rail-group-toggle:focus-visible, .nav-group.open .rail-group-toggle { background: var(--surface); color: var(--side-accent); box-shadow: var(--shadow); }
  .rail-flyout { display: none; position: absolute; top: 0; left: 62px; width: 236px; padding: 14px; border: 1px solid var(--border); border-radius: 20px; background: var(--surface); box-shadow: var(--shadow-pop); z-index: 30; }
  .nav-group:hover > .rail-flyout, .nav-group:focus-within > .rail-flyout, .nav-group.open > .rail-flyout { display: flex; flex-direction: column; gap: 2px; }
  .rail-flyout .nav-head { display: block; margin: 2px 10px 8px; }
  .rail-flyout .nav-item { border-radius: 11px; }
  .nav-foot { flex-direction: column; width: 100%; padding: 14px 0 0; margin-top: auto; border: 0; }
  .nav-foot .nav-item { width: 60px; height: 60px; padding: 0; justify-content: center; border-radius: 18px; }
  .nav-foot .nav-item .txt { display: none; }
  .nav-foot .ghost-btn { font-size: 11px; padding: 7px; }
  .main-wrap { border-radius: 0; min-height: 100vh; }
  .topbar { min-height: 124px; padding: 25px clamp(30px, 4vw, 72px); border: 0; border-radius: 0; }
  .searchbox { max-width: 320px; margin-left: auto; }
  .searchbox input[type="search"] { border: 0; min-height: 48px; box-shadow: var(--shadow); }
  main { padding: 24px clamp(30px, 4vw, 72px) 80px; max-width: 1680px; margin: 0 auto; }
}

@media (max-width: 1180px) and (min-width: 861px) { .top-links { display: none; } }
@media (max-width: 860px) {
  .sidebar { position: relative; z-index: 20; gap: 4px; padding: 10px 14px; align-items: center; }
  .brand { flex: 0 0 100%; padding: 4px 2px 8px; }
  .brand-mark { width: 36px; height: 36px; }
  .nav-group { position: relative; flex: 0 0 auto; }
  .dashboard-group .nav-item, .rail-group-toggle { display: grid; place-items: center; width: 43px; height: 43px; padding: 0; border: 0; border-radius: 13px; background: transparent; color: var(--side-ink); }
  .dashboard-group .nav-item .txt, .dashboard-group .nav-item .count { display: none; }
  .dashboard-group .nav-item .ico, .rail-group-toggle .ico { width: 19px; height: 19px; }
  .dashboard-group .nav-item.active, .rail-group-toggle.active, .nav-group.open .rail-group-toggle { background: var(--surface); color: var(--side-accent); box-shadow: var(--shadow); }
  .rail-group-toggle { cursor: pointer; }
  .rail-lock-badge { right: 0; bottom: 0; width: 10px; height: 10px; }
  .rail-flyout { display: none; position: absolute; top: 48px; left: 0; z-index: 30; flex-direction: column; width: min(220px, calc(100vw - 28px)); padding: 12px; border: 1px solid var(--border); border-radius: 18px; background: var(--surface); box-shadow: var(--shadow-pop); }
  .nav-group.open > .rail-flyout, .nav-group:focus-within > .rail-flyout { display: flex; }
  .rail-flyout .nav-item { padding: 10px 12px; }
  .rail-flyout .nav-head { display: block; margin: 0 10px 6px; }
  .nav-group[data-module="health"] .rail-flyout, .nav-group[data-module="things"] .rail-flyout, .nav-group:not([data-module]):not(.dashboard-group) .rail-flyout { left: auto; right: 0; }
  .nav-foot { margin-left: auto; padding: 0; }
  .nav-foot .nav-item { display: none; }
  .nav-foot .ghost-btn { font-size: 11px; padding: 7px; }
  .top-links { display: none; }
  .topbar { flex-wrap: wrap; }
  .topbar-actions { margin-left: 0; }
  .dashboard-intro { margin-bottom: 32px; }
}
@media (max-width: 600px) {
  .dashboard-intro { display: block; }
  .dashboard-date { margin-top: 22px; width: fit-content; }
  .topbar-actions .unlock-state { display: none; }
  .tile { min-height: 138px; padding: 18px; }
  .tile .tile-ico { top: 16px; left: 16px; }
  .tile .label { margin-top: 49px; }
  .card { padding: 20px; }
}
@media print { .topbar-actions, .top-links { display: none !important; } }

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    --shell: #1e2130; --plane: #252938; --surface: #303547; --surface-2: #282d3d;
    --ink: #f5f5fb; --ink-2: #d8d9e8; --ink-muted: #afb4c8;
    --border: #42485a; --rule: #42485a;
    --side-ink: #aab0c7; --side-ink-hi: #f5f5fb; --side-accent: #b8adff;
    --side-hover: #34394d; --side-active: #303547;
    --accent: #b8adff; --accent-soft: #414062;
    --tile-1: #454167; --tile-1-ink: #c2bbff;
    --tile-2: #59415e; --tile-2-ink: #f0b2df;
    --tile-3: #315c4d; --tile-3-ink: #9ee4bf;
    --tile-4: #344e6f; --tile-4-ink: #abcfff;
  }
}
:root[data-theme="dark"] {
  --shell: #1e2130; --plane: #252938; --surface: #303547; --surface-2: #282d3d;
  --ink: #f5f5fb; --ink-2: #d8d9e8; --ink-muted: #afb4c8;
  --border: #42485a; --rule: #42485a;
  --side-ink: #aab0c7; --side-ink-hi: #f5f5fb; --side-accent: #b8adff;
  --side-hover: #34394d; --side-active: #303547;
  --accent: #b8adff; --accent-soft: #414062;
  --tile-1: #454167; --tile-1-ink: #c2bbff;
  --tile-2: #59415e; --tile-2-ink: #f0b2df;
  --tile-3: #315c4d; --tile-3-ink: #9ee4bf;
  --tile-4: #344e6f; --tile-4-ink: #abcfff;
}
:root[data-theme="dark"] .tile:nth-child(4n+1) .tile-ico { background: var(--tile-1); }
:root[data-theme="dark"] .tile:nth-child(4n+2) .tile-ico { background: var(--tile-2); }
:root[data-theme="dark"] .tile:nth-child(4n+3) .tile-ico { background: var(--tile-3); }
:root[data-theme="dark"] .tile:nth-child(4n) .tile-ico { background: var(--tile-4); }

/* Confirming a sensitive action in place (ADR 0007): a code from the mail, or the second factor, asked for in a dialog over the page. */
.modal-backdrop { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 16px; background: rgba(20, 24, 40, 0.45); }
.modal { width: min(440px, 100%); max-height: calc(100vh - 32px); overflow: auto; padding: 24px; border-radius: var(--radius, 16px); background: var(--surface, #fff); color: var(--ink); border: 1px solid var(--border); box-shadow: var(--shadow-pop, 0 16px 42px rgba(37, 42, 59, 0.2)); }

/* Account settings are a separate surface over the current page. */
body.settings-open { overflow: hidden; }
.settings-backdrop {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  padding: 24px; background: rgba(26, 29, 43, .56);
}
.settings-dialog {
  width: min(1240px, 100%); height: min(900px, calc(100dvh - 48px));
  display: grid; grid-template-columns: 244px minmax(0, 1fr);
  overflow: hidden; border: 1px solid var(--border); border-radius: 22px;
  background: var(--surface); color: var(--ink); box-shadow: 0 24px 80px rgba(16, 19, 35, .24);
}
.settings-side {
  min-width: 0; display: flex; flex-direction: column; gap: 22px;
  padding: 31px 15px 22px; border-right: 1px solid var(--border);
  background: var(--surface-2); overflow-y: auto;
}
.settings-side-heading { padding: 0 13px; color: var(--ink-muted); font-size: 12px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; }
.settings-nav { display: flex; flex-direction: column; gap: 3px; }
.settings-tab {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 11px 13px; border: 0; border-radius: 12px;
  background: transparent; color: var(--ink-2); font: inherit; font-size: 14px;
  text-align: left; cursor: pointer;
}
.settings-tab svg { width: 19px; height: 19px; flex: none; }
.settings-tab:hover { background: var(--side-hover); color: var(--ink); }
.settings-tab.active { background: var(--side-active); color: var(--ink); font-weight: 650; }
.settings-side-account { margin-top: auto; padding: 0 13px; color: var(--ink-muted); font-size: 12px; overflow-wrap: anywhere; }
.settings-main { min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.settings-header { display: flex; align-items: center; justify-content: space-between; flex: none; padding: 22px 38px 10px; }
.settings-header h1 { font-size: 17px; font-weight: 650; margin: 0; }
.settings-close { width: 38px; height: 38px; display: grid; place-items: center; border: 0; border-radius: 10px; background: transparent; color: var(--ink-2); font: 30px/1 var(--sans); cursor: pointer; }
.settings-close:hover { background: var(--surface-2); color: var(--ink); }
.settings-scroll { min-height: 0; overflow-y: auto; padding: 16px 44px 54px 38px; scrollbar-gutter: stable; }
.settings-panel-title { font-size: 26px; letter-spacing: -.035em; margin: 0 0 4px; }
.settings-panel-description { color: var(--ink-muted); font-size: 14px; margin: 0 0 25px; }
.settings-pane .settings-section {
  margin: 0; padding: 25px 0; border: 0; border-top: 1px solid var(--rule);
  border-radius: 0; background: transparent; box-shadow: none;
}
.settings-pane .settings-section:first-child { border-top: 0; padding-top: 0; }
.settings-pane .settings-section h2 { font-size: 18px; margin: 0 0 12px; }
.settings-pane .settings-row { padding: 17px 0; }
.settings-pane .settings-row:first-of-type { border-top: 0; }
.settings-pane .settings-row .title { color: var(--ink); }
.settings-pane .settings-row input:not([type="checkbox"]), .settings-pane .settings-row select { width: min(270px, 46%); flex: none; }
.settings-error { display: block; height: auto; padding: 30px; }
.settings-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; }
.settings-loading h1 { margin: 0; font-size: 24px; }
.settings-loading p { margin: 0; }

@media (max-width: 720px) {
  .settings-backdrop { padding: 0; }
  .settings-dialog { width: 100%; height: 100dvh; border: 0; border-radius: 0; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .settings-side { gap: 10px; padding: 15px 16px 10px; border-right: 0; border-bottom: 1px solid var(--border); overflow: visible; }
  .settings-side-heading { padding: 0 4px; }
  .settings-nav { flex-direction: row; gap: 5px; overflow-x: auto; padding-bottom: 3px; scrollbar-width: thin; }
  .settings-tab { flex: none; width: auto; padding: 9px 11px; white-space: nowrap; }
  .settings-tab svg { width: 16px; height: 16px; }
  .settings-side-account { display: none; }
  .settings-header { padding: 15px 20px 4px; }
  .settings-scroll { padding: 14px 20px 38px; }
  .settings-pane .settings-row { flex-wrap: wrap; align-items: flex-start; }
  .settings-pane .settings-row input:not([type="checkbox"]), .settings-pane .settings-row select { width: 100%; }
}
.modal h2 { margin: 0 0 14px; font-size: 20px; }
.modal .btn-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 14px; }
