/* PoolQuant — desktop redesign (Phase 1: tokens + shell)
 *
 * This file holds the new design system (--pq-* tokens, sidebar,
 * topbar, sparkline, chip, composer-style) for the desktop redesign
 * by Joel.  It coexists with the existing `system.css` mobile-first
 * styles: tokens are scoped to .pq-redesign-root so they don't leak
 * into legacy components, and all layout changes are gated behind
 * `@media (min-width: 1024px)` so phones / narrow tablets keep the
 * existing column-based mobile layout untouched.
 *
 * Phase 1 wires up the shell only — sidebar, topbar, content area
 * and composer placement.  The screen-internals (Today's metric
 * strip, the pool-list table, etc.) come in subsequent phases.
 */


/* ── tokens ────────────────────────────────────────────────────── */
.pq-redesign-root {
  /* Surfaces */
  --pq-bg: #f4f1ea;
  --pq-bg-2: #ebe7dd;
  --pq-surface: #fbf9f3;
  --pq-surface-2: #ffffff;
  --pq-ink: #0c1418;
  --pq-ink-2: #1c2a31;
  --pq-muted: #8a847a;
  --pq-muted-2: #b8b2a6;
  --pq-line: #e2dcd0;
  --pq-line-2: #ece6d8;

  /* Status — aliased to the canonical --ok/--warn/--bad in system.css so
     the same metric paints the same red across /today (redesign palette)
     and /measurements (system palette). The -soft surfaces stay redesign-
     specific (lower-saturation tints layered on cream paper). */
  --pq-red: var(--bad);
  --pq-red-soft: #e8d3cc;
  --pq-amber: var(--warn);
  --pq-amber-soft: #ecdfc4;
  --pq-green: var(--ok);
  --pq-green-soft: #d6dfd5;
  --pq-blue: #36647e;
  --pq-blue-soft: #cfd9e0;

  /* Type — Joel's redesign uses Newsreader (serif) + Geist (sans) +
     JetBrains Mono (numerics).  Loaded alongside the existing fonts
     in base.html.  Mobile chrome keeps Inter Tight / Source Serif via
     its own --type-* tokens; --pq-* points at the redesign fonts so
     the desktop chrome matches the mock voice. */
  --pq-serif: "Newsreader", "Source Serif 4", Georgia, serif;
  --pq-sans:  "Geist", "Inter Tight", ui-sans-serif, system-ui, sans-serif;
  --pq-mono:  "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Radii */
  --pq-r-sm: 4px;
  --pq-r:    6px;
  --pq-r-lg: 10px;
  --pq-r-pill: 999px;

  /* Spacing */
  --pq-gap:   12px;
  --pq-gap-2: 20px;
  --pq-gap-3: 32px;
}


/* ── shared base (all viewports) ────────────────────────────────── */
/* The desktop-only chrome (sidebar + topbar) lives in the same DOM
 * as the existing mobile chrome (.pq-toolbar).  Hide them on mobile
 * by default; the @media block below shows them on >=1024px. */
.pq-side,
.pq-topbar,
.pq-pools-desktop {
  display: none;
}

/* The standalone "asked"/"answered" author tag is desktop-only.
   On mobile we keep the inline " asked" suffix that's been there. */
.nb-author-tag { display: none; }

/* Now-zoom desktop editorial header — hidden on mobile (the legacy
   nb-now-eyebrow handles mobile). */
.pq-now-head { display: none; }
.pq-page-head { display: none; }

/* ── Desktop-only chrome elements that leak into mobile ─────────────
   These elements render unconditionally in the templates so the
   desktop @media block can lay them out.  Mobile shows the legacy
   `nb-*` chrome below them; we hide the redesign duplicates here.
   Each is re-shown at >=1024px inside the @media block via existing
   layout rules (display: grid / flex). */
.pq-day-eyebrow,
.pq-day-headline,
.pq-metric-strip,
.pq-meas-head,
.pq-meas-stats,
.pq-today-rail,
.pq-summary-rail,
.pq-summary-toc,
.nb-composer-context,
.nb-composer-kbd {
  display: none;
}
/* The grid wrappers themselves render as plain blocks on mobile so
   their children stack normally. The desktop @media block converts
   them to grids. */
.pq-today-grid,
.pq-summary-grid {
  display: block;
}
@media (min-width: 1024px) {
  .nb-author-tag-inline { display: none; }
  /* Hide the legacy mobile sticky topbars on desktop — the new
     pq-topbar replaces them.  Mobile (<1024px) keeps these. */
  body.pq-redesign-root .nb-account-topbar,
  body.pq-redesign-root .nb-home-topbar { display: none; }
  /* Account / admin / manage pages: drop the narrow centered column
     on desktop so the content fills the main pane the same way the
     pool pages do. */
  body.pq-redesign-root .nb-account-shell,
  body.pq-redesign-root .nb-account-page,
  body.pq-redesign-root .nb-pool-page {
    max-width: none !important;
    margin: 0 !important;
    padding: 24px 36px !important;
    background: transparent !important;
  }
  /* The shell itself must scroll — .nb-shell is height:100vh; overflow:
     hidden, and these pages don't carry an inner .nb-col scroll
     container the way pool views do, so without this their content past
     the viewport gets silently clipped. */
  body.pq-redesign-root .nb-account-shell,
  body.pq-redesign-root .nb-pool-page {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }
}

/* .pq-main wraps the existing page content (toolbar + nb-col + composer).
 * On mobile it just needs to act as a transparent flex pass-through so
 * .nb-col's `flex: 1` inside still grows to fill nb-shell's height —
 * without this, .nb-col doesn't have a flex container above it any more
 * and the composer slides up to mid-page on short content. */
.pq-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  flex: 1;
}


/* ── desktop-only shell ─────────────────────────────────────────── */
/* Below 1024px, none of these rules fire — the existing mobile
 * layout (.nb-shell column flex + .pq-toolbar) takes over. */
@media (min-width: 1024px) {

  /* Convert the existing .nb-shell into a 2-column grid.  The
     sidebar takes the first column; .pq-main fills the rest.
     `height: 100vh; overflow: hidden` makes the main column the
     scroll container instead of the page, mirroring the redesign
     mockups (sidebar stays put, content scrolls). */
  .pq-redesign-root .nb-shell {
    display: grid;
    grid-template-columns: 232px 1fr;
    grid-template-rows: 100%;
    height: 100vh;
    min-height: 100vh;
    overflow: hidden;
    background: var(--pq-bg);
    font-family: var(--pq-sans);
    color: var(--pq-ink);
  }

  /* Hide the legacy mobile toolbar — replaced by the desktop topbar
     inside .pq-main below. */
  .pq-redesign-root .pq-toolbar { display: none; }

  /* Sidebar ───────────────────────────────────────────────────── */
  .pq-side {
    grid-row: 1;
    grid-column: 1;
    border-right: 1px solid var(--pq-line);
    background: linear-gradient(180deg, var(--pq-bg) 0%, #efebe1 100%);
    display: flex;
    flex-direction: column;
    padding: 16px 14px;
    gap: 14px;
    min-height: 0;
    overflow-y: auto;
  }
  .pq-side .brand {
    display: flex; align-items: center; gap: 10px;
    padding: 4px 6px;
  }
  .pq-side .brand .glyph {
    width: 24px; height: 24px;
    border-radius: 6px;
    background: var(--pq-ink);
    color: #f4f1ea;
    display: grid; place-items: center;
  }
  .pq-side .brand .name {
    font-weight: 600; font-size: 14px;
    letter-spacing: -0.01em;
    color: var(--pq-ink);
    text-decoration: none;
  }
  .pq-side .brand .alpha {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    margin-left: auto;
  }
  .pq-side .search {
    position: relative;
  }
  .pq-side .search input {
    width: 100%; height: 32px;
    padding: 0 32px 0 28px;
    border: 1px solid var(--pq-line);
    border-radius: var(--pq-r);
    background: var(--pq-surface);
    font-family: var(--pq-sans);
    font-size: 12px;
    color: var(--pq-ink);
    outline: none;
  }
  .pq-side .search input::placeholder { color: var(--pq-muted); }
  .pq-side .search .ico {
    position: absolute; left: 8px; top: 9px;
    width: 14px; height: 14px;
    color: var(--pq-muted);
  }
  .pq-side .search .kbd {
    position: absolute; right: 8px; top: 8px;
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    border: 1px solid var(--pq-line);
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--pq-surface);
  }
  .pq-side .section-label {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 0 8px;
    margin-top: 6px;
  }

  .pq-pool-row {
    display: flex; align-items: center; gap: 10px;
    padding: 6px 8px;
    border-radius: 5px;
    font-size: 13px;
    text-decoration: none;
    color: inherit;
  }
  .pq-pool-row:hover { background: rgba(0,0,0,0.03); }
  .pq-pool-row .sw {
    width: 18px; height: 18px;
    border-radius: 4px;
    background: linear-gradient(135deg, #386b86, #5b9ab0);
    flex-shrink: 0;
    overflow: hidden;
  }
  .pq-pool-row .sw[data-tone="green"],
  .pq-pool-row .sw[data-tone="ok"]    { background: linear-gradient(135deg, #4f6f56, #7c9b73); }
  .pq-pool-row .sw[data-tone="amber"],
  .pq-pool-row .sw[data-tone="warn"]  { background: linear-gradient(135deg, #b88a2a, #d6b35b); }
  .pq-pool-row .sw[data-tone="red"],
  .pq-pool-row .sw[data-tone="bad"]   { background: linear-gradient(135deg, #b8412c, #d36c5b); }
  .pq-pool-row .sw[data-tone="muted"] { background: linear-gradient(135deg, #b8b2a6, #d2cdc1); }
  .pq-pool-row .sw img { width: 100%; height: 100%; object-fit: cover; }
  .pq-pool-row .meta { display: flex; flex-direction: column; line-height: 1.15; flex: 1; min-width: 0; }
  .pq-pool-row .nm {
    font-weight: 500; color: var(--pq-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pq-pool-row .sub {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    /* One-line clamp keeps rail rhythm even — long alert messages were
       wrapping to 3-4 lines and producing ragged row heights (#7). */
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    min-width: 0;
  }
  .pq-pool-row[data-active="true"] {
    /* 2px brand left rail + bolder name lifts the active row out of
       the faint surface tint, which on its own was nearly invisible
       at this contrast ratio. The negative left padding keeps the
       text x-position stable with inactive rows. */
    background: var(--pq-surface-2);
    box-shadow: inset 2px 0 0 var(--brand), 0 0 0 1px var(--pq-line) inset;
  }
  .pq-pool-row[data-active="true"] .nm {
    color: var(--pq-ink);
    font-weight: 600;
  }
  /* Right edge gets a few px of padding so the chevron column on
     /app rows isn't flush against the rail edge. */
  .pq-pool-row {
    padding-right: 12px;
  }

  .pq-nav {
    display: flex; flex-direction: column; gap: 2px;
  }
  .pq-nav .item {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 8px;
    border-radius: 5px;
    font-size: 13px;
    color: var(--pq-ink-2);
    text-decoration: none;
  }
  .pq-nav .item:hover { background: rgba(0,0,0,0.03); }
  .pq-nav .item .ico { width: 14px; height: 14px; opacity: 0.7; flex-shrink: 0; }
  .pq-nav .item .lbl { flex: 1; }
  .pq-nav .item .badge {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }
  .pq-nav .item[data-active="true"] {
    /* 2px brand left rail + ink-1 weight 600 text — the prior surface
       tint alone was illegible against the cream sidebar. */
    background: var(--pq-surface-2);
    color: var(--pq-ink);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--brand), 0 0 0 1px var(--pq-line) inset;
  }
  .pq-nav .item[data-state="bad"] .badge { color: var(--pq-red); }

  .pq-side .footer {
    margin-top: auto;
    display: flex; align-items: center; gap: 10px;
    padding: 8px;
    border-top: 1px solid var(--pq-line);
  }
  .pq-side .footer .av {
    width: 26px; height: 26px;
    border-radius: 50%;
    background: #d2c9b4; color: var(--pq-ink-2);
    display: grid; place-items: center;
    font-weight: 600; font-size: 11px;
  }
  .pq-side .footer .who { display: flex; flex-direction: column; line-height: 1.15; flex: 1; min-width: 0; }
  .pq-side .footer .who .nm { font-size: 12px; font-weight: 500; color: var(--pq-ink); }
  .pq-side .footer .who .em {
    font-family: var(--pq-mono);
    font-size: 10px; color: var(--pq-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pq-side .footer a {
    color: var(--pq-muted);
    text-decoration: none;
  }
  .pq-side .footer a:hover { color: var(--pq-ink); }


  /* Main column ──────────────────────────────────────────────── */
  .pq-main {
    grid-row: 1;
    grid-column: 2;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--pq-bg);
  }


  /* Topbar ───────────────────────────────────────────────────── */
  .pq-topbar {
    display: flex; align-items: center; gap: 12px;
    height: 48px;
    flex-shrink: 0;
    padding: 0 20px;
    border-bottom: 1px solid var(--pq-line);
    background: var(--pq-bg);
  }
  .pq-topbar .crumbs {
    display: flex; align-items: center; gap: 8px;
    font-size: 12px;
    color: var(--pq-muted);
  }
  .pq-topbar .crumbs .sep { color: var(--pq-muted-2); }
  .pq-topbar .crumbs .here { color: var(--pq-ink); }
  .pq-topbar .crumbs a {
    color: inherit;
    text-decoration: none;
  }
  .pq-topbar .crumbs a:hover { color: var(--pq-ink); }
  .pq-topbar .spacer { flex: 1; }

  .pq-topbar .seg {
    display: flex; align-items: center;
    padding: 2px;
    background: var(--pq-bg-2);
    border-radius: var(--pq-r-pill);
    height: 28px;
  }
  .pq-topbar .seg a {
    border: none;
    background: transparent;
    padding: 0 12px;
    height: 24px;
    border-radius: var(--pq-r-pill);
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-ink-2);
    letter-spacing: 0.02em;
    text-decoration: none;
    display: inline-flex; align-items: center;
  }
  .pq-topbar .seg a[data-active="true"] {
    /* Active zoom pill uses --brand-droplet (secondary brand voice)
       instead of pure ink — reads as a brand moment, not a default-
       action "selected" state. Text stays --brand-deep for legibility
       on the lighter fill. */
    background: var(--brand-droplet);
    color: var(--brand-deep);
  }

  .pq-topbar .icon-btn {
    width: 28px; height: 28px;
    display: grid; place-items: center;
    border-radius: 5px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--pq-ink-2);
    cursor: pointer;
    text-decoration: none;
  }
  .pq-topbar .icon-btn:hover { background: var(--pq-bg-2); }


  /* Content area ─────────────────────────────────────────────── */
  /* The page body lives here; sets up the scroll container. The
     existing .nb-col centred-narrow column rule still applies on
     mobile, but on desktop we widen it and left-align since the
     redesign's main column is meant to fill the pane (Joel's mock
     uses padding 20px 28px with no max-width constraint). */
  .pq-redesign-root .nb-shell .nb-col {
    overflow-y: auto;
    flex: 1;
    min-height: 0;
    max-width: none;
    margin: 0;
    padding: 24px 36px 80px;
    width: auto;
  }
  .pq-redesign-root .nb-shell .nb-col.wide {
    max-width: none;
  }


  /* ── Custom scrollbars on every desktop scroll container.  Default
     browser bars look heavy against the cream surfaces; thin
     overlay-style bars match the editorial voice better. */
  .pq-redesign-root .pq-main,
  .pq-redesign-root .pq-main *,
  .pq-redesign-root .pq-today-main,
  .pq-redesign-root .pq-today-rail,
  .pq-redesign-root .pq-summary-rail,
  .pq-redesign-root .nb-col,
  .pq-redesign-root .pq-pools-desktop {
    scrollbar-width: thin;
    scrollbar-color: var(--pq-muted-2) transparent;
  }
  .pq-redesign-root *::-webkit-scrollbar { width: 8px; height: 8px; }
  .pq-redesign-root *::-webkit-scrollbar-track { background: transparent; }
  .pq-redesign-root *::-webkit-scrollbar-thumb {
    background: var(--pq-muted-2);
    border-radius: 4px;
    border: 2px solid var(--pq-bg);
    background-clip: padding-box;
  }
  .pq-redesign-root *::-webkit-scrollbar-thumb:hover {
    background: var(--pq-muted);
    background-clip: padding-box;
  }
  .pq-redesign-root *::-webkit-scrollbar-corner { background: transparent; }


  /* ── Sidebar search input (matches chrome.jsx Sidebar) ─── */
  .pq-redesign-root .pq-side-search {
    position: relative;
    margin-bottom: 4px;
  }
  .pq-redesign-root .pq-side-search-icon {
    position: absolute;
    left: 9px;
    top: 9px;
    color: var(--pq-muted);
    pointer-events: none;
  }
  .pq-redesign-root .pq-side-search-input {
    height: 30px;
    padding-left: 30px;
    padding-right: 38px;
    font-size: 12px;
    width: 100%;
  }
  .pq-redesign-root .pq-side-search .kbd {
    position: absolute;
    right: 8px;
    top: 7px;
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    border: 1px solid var(--pq-line);
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--pq-surface);
    pointer-events: none;
  }

  /* ── Sidebar nav badges (counts on Today / Measurements / Routines) */
  .pq-redesign-root .pq-side .pq-nav .item .badge {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    margin-left: auto;
    padding: 0;
  }
  .pq-redesign-root .pq-side .pq-nav .item[data-state="bad"] .badge {
    color: var(--pq-red);
  }


  /* ── Composer harmonisation ─────────────────────────────────
     Joel's design has a single 56px-ish bottom omnibar pinned at
     the foot of .pq-main — same look on Now / Today / Weeks /
     All.  Our .nb-composer-wrap is the existing mobile composer;
     on desktop we pin it to the bottom of pq-main with a top
     border so it reads as one piece across screens. */
  .pq-redesign-root .pq-main > .nb-composer-wrap,
  .pq-redesign-root .pq-main .nb-composer-wrap {
    position: relative;
    bottom: auto;
    border-top: 1px solid var(--pq-line);
    background: var(--pq-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    padding: 10px 24px;
    margin: 0;
    width: 100%;
    max-width: none;
    flex-shrink: 0;
    /* Keep the composer at the bottom of pq-main (which is
       a height-constrained flex column). */
  }
  .pq-redesign-root .nb-composer-wrap form,
  .pq-redesign-root .nb-composer-wrap .nb-composer {
    max-width: none;
    width: 100%;
  }
  /* Context label — "→ MAPLE GROVE · TODAY" mono uppercase muted, sits
     inside the input row before the camera button.  Hidden on mobile
     via @media outside (the redesign root applies on mobile too but
     this rule only activates on desktop). */
  .pq-redesign-root .nb-composer-context {
    display: inline-block;
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
    align-self: center;
    margin-right: 4px;
    flex-shrink: 0;
  }
  /* ⌘↵ keyboard hint inside the composer pill, before the send button. */
  .pq-redesign-root .nb-composer-pill {
    position: relative;
  }
  .pq-redesign-root .nb-composer-kbd {
    position: absolute;
    right: 40px;
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    user-select: none;
    pointer-events: none;
    background: var(--paper-2);
    padding: 0 4px;
  }
  /* Reserve room on the textarea for the kbd hint to sit over */
  .pq-redesign-root .nb-composer-pill textarea {
    padding-right: 78px !important;
  }
  /* Within the today-grid, the composer should sit BELOW the
     two-column grid — make sure pq-main flex order keeps it last. */
  .pq-redesign-root .pq-today-grid + .nb-composer-wrap,
  .pq-redesign-root .pq-main > .pq-today-grid ~ .nb-composer-wrap {
    flex-shrink: 0;
  }


  /* Composer placement on desktop ───────────────────────────── */
  /* The existing composer is `position: sticky; bottom: 0` inside
     a scrolling page.  In the redesign, the composer pins to the
     bottom of the main column (not the viewport).  Since pq-main
     is a height-constrained flex column, the composer at its end
     is naturally at the column bottom. Drop the sticky positioning
     and the frosted-glass treatment on desktop — the simpler
     placement reads as a clean tray. */
  .pq-redesign-root .nb-composer-wrap {
    position: relative;
    background: var(--pq-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-top: 1px solid var(--pq-line);
    box-shadow: none;
    /* Live in pq-main as a flex item; the .nb-col scrolls above. */
  }


  /* Sparkline (used in subsequent phases inside trend chips, but
     declared here so the design system is complete in one file). */
  .pq-spark {
    width: 100%;
    height: 32px;
    display: block;
  }


  /* Chip (status-aware key-value chip) — for future phases. */
  .pq-chip {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 4px 10px;
    border-radius: var(--pq-r-pill);
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    font-family: var(--pq-mono);
    font-size: 11px;
  }
  .pq-chip .k {
    color: var(--pq-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 10px;
  }
  .pq-chip .v { color: var(--pq-ink); }
  .pq-chip[data-state="bad"]  { border-color: rgba(184,65,44,.4);  background: #fbeee9; }
  .pq-chip[data-state="bad"] .v  { color: var(--pq-red); }
  .pq-chip[data-state="warn"] { border-color: rgba(184,138,42,.4); background: #faf2dd; }
  .pq-chip[data-state="warn"] .v { color: var(--pq-amber); }
  .pq-chip[data-state="ok"]   { border-color: rgba(79,111,86,.35); background: #e8efe6; }
  .pq-chip[data-state="ok"] .v   { color: var(--pq-green); }


  /* Status text colors */
  .t-red    { color: var(--pq-red); }
  .t-amber  { color: var(--pq-amber); }
  .t-green  { color: var(--pq-green); }
  .t-muted  { color: var(--pq-muted); }

  /* ── Joel's typographic utilities ───────────────────────────────
     Required by every desktop screen: every "eyebrow" header, every
     numeric value, every section title, the divider lines, the
     surface cards.  Without these the redesign reverts to system
     sans-serif at default sizes. */
  .pq-redesign-root .pq-eyebrow {
    font-family: var(--pq-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--pq-muted);
    font-weight: 500;
    line-height: 1.4;
    margin: 0;
  }
  .pq-redesign-root .pq-mono {
    font-family: var(--pq-mono);
    font-feature-settings: "zero", "ss01";
    letter-spacing: 0;
  }
  .pq-redesign-root .pq-serif {
    font-family: var(--pq-serif);
    letter-spacing: -0.01em;
  }
  .pq-redesign-root .pq-num {
    font-family: var(--pq-mono);
    font-feature-settings: "tnum", "zero";
    letter-spacing: -0.01em;
  }
  .pq-redesign-root .pq-h1 {
    font-family: var(--pq-serif);
    font-weight: 500;
    font-size: 38px;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--pq-ink);
    margin: 0;
  }
  .pq-redesign-root .pq-h2 {
    font-family: var(--pq-serif);
    font-weight: 500;
    font-size: 24px;
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--pq-ink);
    margin: 0;
  }
  .pq-redesign-root .pq-h3 {
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -0.005em;
    color: var(--pq-ink);
    margin: 0;
  }
  .pq-redesign-root .pq-divider {
    height: 1px;
    background: var(--pq-line);
    width: 100%;
    border: none;
    margin: 0;
  }
  .pq-redesign-root .pq-card {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: var(--pq-r);
  }
  .pq-redesign-root .pq-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 32px;
    padding: 0 14px;
    font-family: var(--pq-sans);
    font-size: 13px;
    font-weight: 500;
    border-radius: var(--pq-r);
    border: 1px solid var(--pq-ink);
    background: var(--pq-ink);
    color: #f4f1ea;
    cursor: pointer;
    text-decoration: none;
  }
  .pq-redesign-root .pq-btn[data-variant="ghost"] {
    background: transparent;
    color: var(--pq-ink);
    border-color: var(--pq-line);
  }


  /* ── Today screen layout ─────────────────────────────────────
     The Day-zoom content (next_steps.html) gets a 1fr / 360px grid
     wrapper at desktop sizes. The main column flows the editorial
     headline + 7-metric strip + today's entries; the right rail
     carries routines / weather / trends / sources today. */
  .pq-redesign-root .pq-today-grid {
    display: grid;
    grid-template-columns: 1fr 360px;
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }
  /* On narrow desktops, shrink the rail so the main column has
     enough width for the headline + metric strip. */
  @media (max-width: 1199px) {
    .pq-redesign-root .pq-today-grid {
      grid-template-columns: 1fr 280px;
    }
  }
  @media (max-width: 1099px) {
    .pq-redesign-root .pq-today-grid {
      /* Bump the rail to 280px (was 240px) so the Routines card
         doesn't wrap every other word at 1024.  Main column still has
         enough room (~700px at 1024) for the metric strip + entries. */
      grid-template-columns: 1fr 280px;
    }
    /* Tighten rail + routine-card padding so the bullet text gets
       a few extra pixels back. */
    .pq-redesign-root .pq-today-rail {
      padding-left: 14px;
      padding-right: 14px;
    }
    .pq-redesign-root .pq-rail-routines {
      padding-left: 8px;
      padding-right: 8px;
    }
  }
  .pq-redesign-root .pq-today-main {
    overflow-y: auto;
    padding: 24px 28px;
    min-width: 0;
  }
  .pq-redesign-root .pq-today-rail {
    border-left: 1px solid var(--pq-line);
    background: var(--pq-bg);
    overflow-y: auto;
    padding: 18px 18px 60px;
    display: flex; flex-direction: column;
    gap: 18px;
  }

  /* On desktop, the existing centred-narrow .nb-col + its stat-strip
     and next-steps section are HIDDEN — replaced by the redesign's
     metric-strip + right-rail equivalents. The existing
     todays-entries-list is reused (re-styled in the entry-row CSS
     elsewhere) so we don't duplicate the chronological log. */
  .pq-redesign-root .pq-today-grid .nb-col { display: contents; }
  .pq-redesign-root .pq-today-grid .nb-stat-strip,
  .pq-redesign-root .pq-today-grid .pq-mobile-only,
  .pq-redesign-root .pq-today-grid .nb-day-eyebrow,
  .pq-redesign-root .pq-today-grid .nb-day-headline { display: none; }
  /* The "Today's entries" h2 gets a subtler eyebrow style on desktop. */
  .pq-redesign-root .pq-today-main .nb-section-label {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-top: 28px;
    margin-bottom: 10px;
  }


  /* Editorial eyebrow + headline ─────────────────────────────── */
  .pq-redesign-root .pq-day-eyebrow {
    display: block;
    font-family: var(--pq-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--pq-muted);
    margin: 0 0 12px;
  }
  .pq-redesign-root .pq-day-headline {
    display: block;
    font-family: var(--pq-serif);
    font-weight: 500;
    font-size: 38px;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--pq-ink);
    margin: 0 0 20px;
    max-width: 760px;
  }
  .pq-redesign-root .pq-day-headline .accent {
    /* Bump weight + size so the accent number ("23" in "Temp is
       running low at 23.") actually dominates the hero rather than
       sitting flush with the surrounding sentence. Inline `style="color"`
       drives hue from the route handler; we touch only weight + size
       here so the accent_color signal still wins. */
    font-weight: 700;
    font-size: 1.1em;
  }
  .pq-redesign-root .pq-day-headline .pq-num {
    font-family: var(--pq-mono);
    font-feature-settings: "tnum", "zero";
    letter-spacing: 0;
  }


  /* 7-metric strip ───────────────────────────────────────────── */
  .pq-redesign-root .pq-metric-strip {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    border: 1px solid var(--pq-line);
    border-radius: 8px;
    background: var(--pq-surface);
    overflow: hidden;
    margin-bottom: 8px;
  }
  /* Joel's design keeps the strip 7-up at every desktop size.  When
     the column gets narrow we shrink padding + font instead of
     wrapping — wrapping creates an asymmetric 4/3 layout that reads
     as broken. */
  @media (max-width: 1279px) {
    .pq-redesign-root .pq-metric-strip .cell {
      padding: 8px 8px;
    }
    .pq-redesign-root .pq-metric-strip .cell .val {
      font-size: 15px;
    }
    .pq-redesign-root .pq-metric-strip .cell .lbl { font-size: 9px; }
    .pq-redesign-root .pq-metric-strip .cell .delta { font-size: 9px; }
  }
  .pq-redesign-root .pq-metric-strip .cell {
    padding: 10px 12px;
    border-right: 1px solid var(--pq-line);
    display: flex; flex-direction: column;
    gap: 2px;
    min-width: 0;
  }
  .pq-redesign-root .pq-metric-strip .cell:last-child { border-right: none; }
  .pq-redesign-root .pq-metric-strip .cell .lbl {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  /* Opt-out: 'pH' would otherwise be uppercased to 'PH' by the rule
     above. Cleared letter-spacing so the lowercase 'p' doesn't pull
     away from the 'H' the way the wider tracking implies. */
  .pq-redesign-root .pq-metric-strip .cell .lbl.lbl-cased {
    text-transform: none;
    letter-spacing: 0.04em;
  }
  /* Same opt-out for the pool-row chip key on /app. */
  .pq-redesign-root .pq-chip .k.k-cased {
    text-transform: none;
    letter-spacing: 0.02em;
  }
  .pq-redesign-root .pq-metric-strip .cell .val {
    font-family: var(--pq-mono);
    font-feature-settings: "tnum";
    font-size: 18px;
    font-weight: 500;
    color: var(--pq-ink);
    letter-spacing: 0;
  }
  .pq-redesign-root .pq-metric-strip .cell .val .u {
    font-size: 10px;
    color: var(--pq-muted);
    margin-left: 3px;
    font-weight: 400;
  }
  .pq-redesign-root .pq-metric-strip .cell .delta {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }
  /* Status-tinted captions — value + caption travel together so "out of
     range" reads at a glance without the eye chasing two color cues. */
  .pq-redesign-root .pq-metric-strip .cell.bad  .delta { color: var(--pq-red); }
  .pq-redesign-root .pq-metric-strip .cell.warn .delta { color: var(--pq-amber); }
  .pq-redesign-root .pq-metric-strip .cell.ok   .delta { color: var(--pq-green); }
  .pq-redesign-root .pq-metric-strip .cell.bad  .val > span:first-child { color: var(--pq-red); }
  .pq-redesign-root .pq-metric-strip .cell.warn .val > span:first-child { color: var(--pq-amber); }
  .pq-redesign-root .pq-metric-strip .cell.ok   .val > span:first-child { color: var(--pq-ink); }
  /* Empty-state cell (e.g. SI before user has logged CYA + CAL + temp +
     TA): single dimmed em-dash with no unit/status sub-line.  We keep
     the cell in the grid (so the 7-up rhythm holds) but dim its label
     + value, and reserve the third row's height with an invisible
     spacer so the cell matches its neighbours. */
  .pq-redesign-root .pq-metric-strip .cell.is-empty .lbl,
  .pq-redesign-root .pq-metric-strip .cell.is-empty .val { color: var(--pq-muted-2); }
  .pq-redesign-root .pq-metric-strip .cell.is-empty::after {
    content: "";
    display: block;
    /* match .delta line-height (font-size 10/9 × ~1.2) */
    min-height: 12px;
  }


  /* Right-rail panels ────────────────────────────────────────── */
  .pq-redesign-root .pq-rail-panel { display: flex; flex-direction: column; gap: 8px; }
  .pq-redesign-root .pq-rail-panel-head {
    display: flex; align-items: center; justify-content: space-between;
  }
  .pq-redesign-root .pq-rail-panel-head .label {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .pq-redesign-root .pq-rail-panel-head .meta {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .pq-rail-card {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: 6px;
  }


  /* Weather card */
  .pq-redesign-root .pq-rail-weather { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
  .pq-redesign-root .pq-rail-weather .days {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    align-items: end;
  }
  .pq-redesign-root .pq-rail-weather .day {
    text-align: center;
    display: flex; flex-direction: column;
    gap: 4px;
  }
  .pq-redesign-root .pq-rail-weather .day .d {
    font-family: var(--pq-mono);
    font-size: 9px;
    color: var(--pq-muted);
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .pq-redesign-root .pq-rail-weather .day .t {
    font-family: var(--pq-mono);
    font-size: 13px;
    font-weight: 500;
  }
  .pq-redesign-root .pq-rail-weather .day .rainwrap {
    height: 28px;
    display: flex; align-items: end; justify-content: center;
    overflow: hidden;     /* belt-and-braces: cap any inline-styled bar */
  }
  .pq-redesign-root .pq-rail-weather .day .rainbar {
    width: 14px;
    background: var(--pq-blue-soft);
    border-radius: 2px;
  }
  .pq-redesign-root .pq-rail-weather .day.heavy .rainbar { background: var(--pq-blue); }
  .pq-redesign-root .pq-rail-weather .day .mm {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .pq-rail-weather .day.heavy .mm { color: var(--pq-blue); }
  .pq-redesign-root .pq-rail-weather .note {
    font-size: 11px;
    color: var(--pq-ink-2);
    border-top: 1px solid var(--pq-line);
    padding-top: 8px;
    line-height: 1.45;
  }
  .pq-redesign-root .pq-rail-weather .note.warn { color: var(--pq-amber); }


  /* Trends card */
  .pq-redesign-root .pq-rail-trends .row {
    display: grid;
    grid-template-columns: 44px 1fr 70px;
    gap: 10px;
    padding: 10px 12px;
    align-items: center;
    border-bottom: 1px solid var(--pq-line);
  }
  .pq-redesign-root .pq-rail-trends .row:last-child { border-bottom: none; }
  .pq-redesign-root .pq-rail-trends .row .k {
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-muted);
    letter-spacing: 0.06em;
  }
  .pq-redesign-root .pq-rail-trends .row .v {
    font-family: var(--pq-mono);
    font-size: 12px;
    text-align: right;
  }
  .pq-redesign-root .pq-rail-trends .row .v.bad   { color: var(--pq-red); }
  .pq-redesign-root .pq-rail-trends .row .v.warn  { color: var(--pq-amber); }
  .pq-redesign-root .pq-rail-trends .row .spark   { height: 24px; }


  /* Sources list */
  .pq-redesign-root .pq-rail-sources {
    display: flex; flex-direction: column; gap: 6px;
    font-size: 11px;
  }
  .pq-redesign-root .pq-rail-sources .src {
    display: flex; align-items: center; gap: 8px;
  }
  .pq-redesign-root .pq-rail-sources .src .dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--pq-green);
    flex-shrink: 0;
  }
  .pq-redesign-root .pq-rail-sources .src.muted .dot { background: var(--pq-muted-2); }
  .pq-redesign-root .pq-rail-sources .src .nm { flex: 1; }
  .pq-redesign-root .pq-rail-sources .src .meta {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }


  /* ── Weekly summary ─────────────────────────────────────────
     /summary becomes a 1fr/320px grid: editorial column on the
     left (existing summary content reuses its legacy classes), a
     sticky right rail with TOC + at-a-glance + ask card. */
  .pq-redesign-root .pq-summary-grid {
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: 32px;
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }
  .pq-redesign-root .pq-summary-main {
    overflow-y: auto;
    padding: 24px 28px 60px;
    min-width: 0;
  }
  .pq-redesign-root .pq-summary-main > .pq-day-eyebrow,
  .pq-redesign-root .pq-summary-main > .pq-day-headline {
    margin-left: 0;
    margin-right: 0;
  }
  /* Mobile-only legacy eyebrow + headline at the top of nb-col are
     hidden on desktop (the new editorial pair above renders
     instead). */
  .pq-redesign-root .pq-summary-grid .nb-col { display: contents; }
  .pq-redesign-root .pq-summary-grid .nb-weeks-eyebrow,
  .pq-redesign-root .pq-summary-grid .nb-weeks-h1 { display: none; }

  .pq-redesign-root .pq-summary-rail {
    border-left: 1px solid var(--pq-line);
    background: var(--pq-bg);
    overflow-y: auto;
    padding: 24px 22px 60px;
    display: flex; flex-direction: column;
    gap: 18px;
  }
  .pq-redesign-root .pq-summary-rail .pq-eyebrow { color: var(--pq-muted); }

  .pq-redesign-root .pq-summary-toc {
    display: flex; flex-direction: column;
    gap: 4px;
    font-size: 12px;
    border-left: 1px solid var(--pq-line);
    padding-left: 12px;
  }
  .pq-redesign-root .pq-summary-toc a {
    color: var(--pq-muted);
    text-decoration: none;
    padding: 3px 0;
    line-height: 1.3;
  }
  .pq-redesign-root .pq-summary-toc a:hover { color: var(--pq-ink); }
  .pq-redesign-root .pq-summary-toc a[data-active="true"] {
    color: var(--pq-ink);
    font-weight: 500;
    margin-left: -13px;
    padding-left: 13px;
    border-left: 2px solid var(--pq-ink);
  }

  .pq-redesign-root .pq-summary-glance {
    padding: 14px;
    display: flex; flex-direction: column;
    gap: 10px;
  }
  .pq-redesign-root .pq-summary-glance-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }

  .pq-redesign-root .pq-summary-ask {
    padding: 14px;
    display: flex; flex-direction: column;
    gap: 8px;
    background: var(--pq-bg);
    border: 1px solid var(--pq-line);
  }
  .pq-redesign-root .pq-summary-ask-hint {
    font-size: 11px;
    color: var(--pq-muted);
    line-height: 1.5;
  }
  .pq-redesign-root .pq-summary-ask-suggestions {
    display: flex; flex-direction: column;
    gap: 4px;
    margin-top: 4px;
  }
  .pq-redesign-root .pq-summary-ask-suggestions a {
    display: inline-flex; align-items: center;
    gap: 8px;
    height: 26px;
    padding: 0 10px;
    border-radius: 999px;
    background: var(--pq-bg-2);
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-ink-2);
    text-decoration: none;
    border: 1px solid transparent;
    transition: background 80ms ease, border-color 80ms ease;
  }
  .pq-redesign-root .pq-summary-ask-suggestions a:hover {
    background: var(--pq-surface);
    border-color: var(--pq-line);
  }
  .pq-redesign-root .pq-summary-ask-suggestions a span { color: var(--pq-muted); }


  /* ── Measurements header ────────────────────────────────────
     /measurements gets an editorial header strip on desktop with
     pool eyebrow + serif h1 + 4-stat row.  The legacy mobile
     header (nb-all-eyebrow / nb-all-h1 inside .nb-col.wide)
     stays for <1024px and is hidden here. */
  .pq-redesign-root .pq-meas-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 24px;
    padding: 24px 28px 12px;
  }
  .pq-redesign-root .pq-meas-head-text { min-width: 0; }
  .pq-redesign-root .pq-meas-head-text .pq-day-headline { margin-bottom: 0; }
  .pq-redesign-root .pq-meas-stats {
    display: flex; gap: 28px; align-items: flex-end;
  }
  .pq-redesign-root .pq-meas-stats > div { display: flex; flex-direction: column; gap: 4px; }

  .pq-redesign-root .nb-col.wide { padding-top: 0; }
  .pq-redesign-root .nb-all-eyebrow,
  .pq-redesign-root .nb-all-h1 { display: none; }


  /* ── Pool list / Workspace ──────────────────────────────────
     On desktop /app uses a table layout instead of the stacked
     accordion. Hide the legacy mobile chrome and reveal the new
     desktop chrome. */
  .pq-redesign-root .pq-pools-mobile { display: none; }
  .pq-redesign-root .pq-pools-desktop { display: block; height: 100%; overflow: auto; }

  .pq-pools-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 36px 36px 60px;
    font-family: var(--pq-sans);
    color: var(--pq-ink);
  }
  .pq-pools-intro { display: flex; flex-direction: column; gap: 4px; margin-bottom: 24px; }
  .pq-pools-intro h1 {
    font-family: var(--pq-serif);
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--pq-ink);
    margin: 0;
  }
  .pq-pools-summary {
    font-size: 13px;
    color: var(--pq-muted);
    max-width: 620px;
    line-height: 1.5;
    margin: 0;
  }

  .pq-pools-table {
    display: flex; flex-direction: column;
    border: 1px solid var(--pq-line);
    border-radius: 8px;
    background: var(--pq-surface);
    overflow: hidden;
  }
  .pq-pools-thead,
  .pq-pool-trow {
    display: grid;
    /* Sparkline column capped at 180px (was 1fr, dominated the row) — pool
       name column gets the spare width back so long names breathe (#6). */
    grid-template-columns: minmax(300px, 1fr) 180px 240px 160px 120px;
    gap: 12px;
    align-items: center;
    padding: 14px 16px;
  }
  /* Narrow desktops can't fit Joel's full 5-column table — shrink
     the fixed columns and tighten gaps below 1200px, and drop the
     last-sync column entirely below 1100px (least critical info). */
  @media (max-width: 1199px) {
    .pq-pools-thead,
    .pq-pool-trow {
      grid-template-columns: minmax(220px, 1fr) 160px 200px 110px 100px;
      gap: 8px;
    }
  }
  @media (max-width: 1099px) {
    .pq-pools-thead,
    .pq-pool-trow {
      grid-template-columns: minmax(200px, 1fr) 140px 200px 100px;
      gap: 8px;
    }
    /* last-sync column (4th of 5) is dropped on narrow desktops */
    .pq-pools-thead > div:nth-child(4),
    .pq-pool-trow .cell-sync {
      display: none;
    }
  }
  .pq-pools-thead {
    border-bottom: 1px solid var(--pq-line);
    background: var(--pq-bg);
    padding: 10px 18px;
  }
  .pq-pool-trow {
    border-bottom: 1px solid var(--pq-line);
    text-decoration: none;
    color: inherit;
    transition: background 80ms ease;
  }
  .pq-pool-trow:last-child { border-bottom: none; }
  .pq-pool-trow:hover { background: rgba(0,0,0,0.025); }

  .pq-pool-trow .cell-name {
    display: flex; align-items: center; gap: 12px;
    min-width: 0;
  }
  .pq-pool-trow .thumb {
    width: 38px; height: 38px;
    border-radius: 6px;
    flex-shrink: 0;
    background: linear-gradient(135deg, #386b86, #5b9ab0);
    overflow: hidden;
  }
  .pq-pool-trow .thumb[data-tone="green"] { background: linear-gradient(135deg, #4f6f56, #7c9b73); }
  .pq-pool-trow .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .pq-pool-trow .info { display: flex; flex-direction: column; min-width: 0; }
  .pq-pool-trow .info .nm {
    font-size: 14px; font-weight: 500;
    color: var(--pq-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pq-pool-trow .info .meta {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }

  .pq-pool-trow .cell-spark {
    height: 36px;
    overflow: hidden;
  }
  /* compute_trends bakes the sparkline SVG with `style="height:110px"`
     inline (designed for the trend cards, where height is much
     bigger). Override here to fit the row. */
  .pq-pool-trow .cell-spark svg {
    display: block;
    width: 100% !important;
    height: 36px !important;
  }
  .pq-pool-trow .cell-spark .empty {
    font-size: 11px;
    color: var(--pq-muted);
    font-style: italic;
  }

  .pq-pool-trow .cell-chips {
    display: flex; flex-wrap: wrap; gap: 6px;
  }
  .pq-pool-trow .cell-chips .pq-chip {
    padding: 2px 8px;
    height: 22px;
  }

  .pq-pool-trow .cell-sync {
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-muted);
  }

  .pq-pool-trow .cell-status {
    display: flex; align-items: center; gap: 10px;
    min-width: 0;
  }
  .pq-pool-trow .cell-status .dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--pq-muted-2);
  }
  .pq-pool-trow .cell-status .dot-ok   { background: var(--pq-green); }
  .pq-pool-trow .cell-status .dot-warn { background: var(--pq-amber); }
  .pq-pool-trow .cell-status .dot-bad  { background: var(--pq-red); }
  .pq-pool-trow .cell-status .txt {
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-ink-2);
    flex: 1;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pq-pool-trow .cell-status .chev {
    color: var(--pq-muted);
    flex-shrink: 0;
    /* Inset the chevron from the row's right edge — it was sitting
       flush against the cell border, which read as clipped on
       narrow desktops + iPhone SE. */
    margin-right: 8px;
  }

  .pq-pools-add {
    margin-top: 20px;
    padding: 16px;
    border: 1px dashed var(--pq-line);
    border-radius: 8px;
    display: flex; align-items: center; gap: 12px;
    background: var(--pq-surface);
  }
  .pq-pools-add .pq-input {
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--pq-line);
    border-radius: 6px;
    background: var(--pq-bg);
    font: inherit;
    font-size: 13px;
    color: var(--pq-ink);
    outline: none;
    max-width: 360px;
    flex: 1;
  }
  /* Workspace activity feed — single chronological column below the
     pool table on /app. Was a 2-up grid that produced a 10-column visual
     mess where you couldn't read entries in time order; the single column
     gives spare width back to author + pool labels at full size (#5). */
  .pq-redesign-root .pq-workspace-activity {
    margin-top: 36px;
  }
  .pq-redesign-root .pq-workspace-activity .pq-eyebrow {
    margin-bottom: 12px;
  }
  .pq-redesign-root .pq-activity-grid {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--pq-line);
    border-radius: 8px;
    background: var(--pq-surface);
    overflow: hidden;
  }
  .pq-redesign-root .pq-activity-row {
    display: grid;
    grid-template-columns: 64px 160px 1fr 200px;
    gap: 14px;
    padding: 10px 16px;
    align-items: center;
    border-bottom: 1px solid var(--pq-line);
    text-decoration: none;
    color: var(--pq-ink-2);
    font-family: var(--pq-sans);
  }
  .pq-redesign-root .pq-activity-row:last-child { border-bottom: none; }
  .pq-redesign-root .pq-activity-row:hover { background: rgba(0,0,0,0.02); }
  .pq-redesign-root .pq-activity-row .when { font-size: 11px; color: var(--pq-muted); }
  .pq-redesign-root .pq-activity-row .who {
    font-size: 10px;
    color: var(--pq-ink-2);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }
  .pq-redesign-root .pq-activity-row .what {
    font-size: 12px;
    color: var(--pq-ink-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .pq-redesign-root .pq-activity-row .where {
    font-size: 10px;
    color: var(--pq-muted);
  }


  .pq-btn-ink {
    height: 32px;
    padding: 0 14px;
    border-radius: 6px;
    background: var(--pq-ink);
    color: #f4f1ea;
    border: 1px solid var(--pq-ink);
    font-family: var(--pq-sans);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
  }
  .pq-pools-empty {
    text-align: center;
    padding: 60px 20px;
  }


  /* Routines card (re-uses next_steps_sections data) */
  .pq-redesign-root .pq-rail-routines {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: 6px;
    padding: 8px 10px;
  }
  .pq-redesign-root .pq-rail-routines .group { padding: 6px 0; }
  .pq-redesign-root .pq-rail-routines .group + .group { border-top: 1px solid var(--pq-line-2); }
  .pq-redesign-root .pq-rail-routines .group .group-label {
    font-family: var(--pq-mono);
    font-size: 9.5px;
    color: var(--pq-muted);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-bottom: 6px;
  }
  .pq-redesign-root .pq-rail-routines .item {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 5px 0;
    font-size: 12px;
    line-height: 1.4;
    color: var(--pq-ink-2);
  }
  /* Rail-routines are decorative (the actual done-toggle UI is on
     mobile/the main column), so use a single solid-dot marker for
     every item — actionable, observation, completed.  Previously
     actionable bullets rendered as a hollow circle that looked like
     an unchecked checkbox sitting next to filled-dot observations,
     which read as inconsistent. */
  .pq-redesign-root .pq-rail-routines .item .marker {
    width: 6px; height: 6px;
    flex-shrink: 0;
    margin-top: 6px;
    margin-left: 4px;
    margin-right: 4px;
    border-radius: 50%;
    background: var(--pq-muted-2);
    border: none;
    display: block;
  }
  .pq-redesign-root .pq-rail-routines .item.priority-high .marker { background: var(--pq-red); }
  .pq-redesign-root .pq-rail-routines .item.is-done .marker { background: var(--pq-green); }
  /* Hide the inline checkmark SVG that the template emits inside
     .marker for completed actionable items — colour change above
     conveys done-state in the rail. */
  .pq-redesign-root .pq-rail-routines .item .marker svg { display: none; }
  .pq-redesign-root .pq-rail-routines .item .body { flex: 1; min-width: 0; }
  .pq-redesign-root .pq-rail-routines .item .task { color: var(--pq-ink); font-weight: 500; }
  .pq-redesign-root .pq-rail-routines .item .why  { color: var(--pq-muted); font-size: 11px; margin-top: 1px; }


  /* Now-zoom editorial header (pq-now-head) — show on desktop, hide
     the legacy small eyebrow that comes after it.  Mobile keeps the
     small eyebrow and hides the serif headline. */
  .pq-redesign-root .pq-now-head { display: block; margin-bottom: 8px; }
  .pq-redesign-root .pq-now-head + .nb-now-eyebrow { display: none; }
  .pq-redesign-root .pq-page-head { display: block; margin-bottom: 18px; }
  /* Hide the legacy h1 inside manage/account when redesign header is present. */
  .pq-redesign-root .pq-page-head + h1,
  .pq-redesign-root .pq-page-head + .nb-section { /* leave nb-section visible */ }
  .pq-redesign-root .pq-page-head + h1 { display: none; }


  /* ── stream entries (Phase 6.2 — match today.jsx Entry component) ──
     The existing markup is a 2-col grid (.nb-entry > div:first-child = ts/who,
     div:nth-child(2) = content, optional .nb-delete).  These rules restyle
     that grid + each kind's content to match Joel's mock exactly on desktop. */

  /* The grid: 78px / 1fr / auto, gap 16, hairline rule below each row.
     The /now (pool) page keeps the wider 78px timestamp column. */
  .pq-redesign-root .nb-col .nb-entry {
    grid-template-columns: 78px 1fr auto !important;
    column-gap: 16px;
    padding: 14px 0;
    border-bottom: 1px solid var(--pq-line);
    border-top: none;
    background: transparent;
    align-items: flex-start;
  }
  /* Day-zoom entries get a tighter 56px column — the 78px was
     orphaning the timestamp+author block ~80px from the entry text
     in the narrower today-main column and reading as unrelated. */
  .pq-redesign-root .pq-today-grid .nb-entry,
  .pq-redesign-root .pq-today-main .nb-entry {
    grid-template-columns: 56px 1fr auto !important;
    column-gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--pq-line);
    border-top: none;
    background: transparent;
    align-items: flex-start;
  }

  /* Left column: timestamp + uppercase source tag (+ asked/answered) */
  .pq-redesign-root .nb-entry .nb-ts {
    font-family: var(--pq-mono);
    font-size: 11px;
    font-weight: 500;
    color: var(--pq-ink-2);
    letter-spacing: 0;
    line-height: 1.2;
    margin: 0;
  }
  .pq-redesign-root .nb-entry .nb-who {
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    line-height: 1.3;
    margin-top: 2px;
    font-weight: 400;
  }
  /* Restore colored author chips on desktop. Joel's mock had a flatter
     muted treatment, but CLAUDE.md mandates branded author colors so the
     stream stays scannable across self / assistant / service-token /
     other-user. Drop the chip background/border (cleaner on a wide canvas)
     but keep the brand color on the text itself. */
  .pq-redesign-root .nb-entry .nb-who .who-tag {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    border-radius: 0 !important;
    font-weight: inherit;
    font-size: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
  }
  .pq-redesign-root .nb-entry .nb-who .who-self  { color: var(--ink); }
  .pq-redesign-root .nb-entry .nb-who .who-bot   { color: var(--brand); }
  .pq-redesign-root .nb-entry .nb-who .who-svc   { color: var(--ok-muted); }
  .pq-redesign-root .nb-entry .nb-who .who-other { color: var(--ink-2); }
  /* "asked" / "answered" tag rendered by template tweak below */
  .pq-redesign-root .nb-entry .nb-author-tag {
    display: block;
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
    text-transform: lowercase;
    letter-spacing: 0;
    margin-top: 1px;
    line-height: 1.3;
  }
  .pq-redesign-root .nb-entry .nb-author-tag.is-answered {
    color: var(--pq-blue);
  }

  /* Reading grid — auto-fill 110px cells, eyebrow + value + status dot */
  .pq-redesign-root .nb-entry .nb-reading-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 10px;
    max-width: 600px;
    border: none;
    background: transparent;
    padding: 0;
    margin: 0;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell {
    display: flex;
    flex-direction: column;
    gap: 1px;
    border: none;
    background: transparent;
    padding: 0;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .nb-reading-label {
    font-family: var(--pq-mono);
    font-size: 9px;
    color: var(--pq-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 500;
    line-height: 1.3;
    margin: 0;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row {
    display: flex;
    align-items: baseline;
    gap: 4px;
    font-family: var(--pq-mono);
    font-size: 14px;
    font-weight: 500;
    color: var(--pq-ink);
    line-height: 1.25;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .nb-reading-mid {
    font-size: 14px;
    font-weight: 500;
    color: inherit;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .nb-reading-unit {
    font-size: 10px;
    color: var(--pq-muted);
    font-weight: 400;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .dot {
    width: auto; height: auto;
    background: transparent !important;
    margin-left: 2px;
    font-size: 10px;
    line-height: 1;
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .dot::before {
    content: "●";
    color: var(--pq-green);
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .dot.warn::before {
    color: var(--pq-amber);
  }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row .dot.bad::before {
    color: var(--pq-red);
  }
  /* Reserve the dot's slot on every chip — the macro only renders a
     .dot element when status != 'ok', which made multi-metric rows
     jitter (in-range chips ended just after the unit, out-of-range
     chips trailed an extra ~10px).  Add an invisible placeholder dot
     after rows that don't already carry one. */
  .pq-redesign-root .nb-entry .nb-reading-grid .cell .row:not(:has(.dot))::after {
    content: "●";
    color: transparent;
    margin-left: 2px;
    font-size: 10px;
    line-height: 1;
  }
  /* Color the value itself by status (sibling of the dot) */
  .pq-redesign-root .nb-entry .nb-reading-grid .cell:has(.dot.warn) .nb-reading-mid { color: var(--pq-amber); }
  .pq-redesign-root .nb-entry .nb-reading-grid .cell:has(.dot.bad)  .nb-reading-mid { color: var(--pq-red); }

  /* Single-metric reading row — restyle as a one-cell grid */
  .pq-redesign-root .nb-entry .nb-reading-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
    font-family: var(--pq-mono);
    line-height: 1.25;
  }
  .pq-redesign-root .nb-entry .nb-reading-row .nb-reading-label {
    font-family: var(--pq-mono);
    font-size: 9px;
    color: var(--pq-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 500;
  }
  .pq-redesign-root .nb-entry .nb-reading-row .nb-reading-big {
    font-size: 14px;
    font-weight: 500;
    color: var(--pq-ink);
  }
  .pq-redesign-root .nb-entry .nb-reading-row .nb-reading-unit {
    font-size: 10px;
    color: var(--pq-muted);
    font-weight: 400;
  }
  .pq-redesign-root .nb-entry .nb-reading-row .range {
    font-family: var(--pq-mono);
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 1px 6px;
    border-radius: 2px;
    margin-left: 4px;
  }
  .pq-redesign-root .nb-entry .nb-reading-row .range.warn {
    color: var(--pq-amber);
    background: var(--pq-amber-soft);
  }
  .pq-redesign-root .nb-entry .nb-reading-row .range.bad {
    color: var(--pq-red);
    background: var(--pq-red-soft);
  }

  /* Note kind — bordered-left subtle text */
  .pq-redesign-root .nb-entry .nb-note {
    font-size: 13px;
    color: var(--pq-ink-2);
    border-left: 2px solid var(--pq-line);
    padding-left: 12px;
    background: transparent;
    margin: 0;
    line-height: 1.5;
    font-family: var(--pq-sans);
  }
  .pq-redesign-root .nb-entry .nb-note p { margin: 0; }
  .pq-redesign-root .nb-entry .nb-note p + p { margin-top: 6px; }

  /* User text inline with extraction (the "raw" block above readings) */
  .pq-redesign-root .nb-entry .nb-user-text {
    font-size: 13px;
    color: var(--pq-ink-2);
    background: transparent;
    border-left: 2px solid var(--pq-line);
    padding: 0 0 0 12px;
    margin: 0 0 10px 0;
    line-height: 1.5;
    font-family: var(--pq-sans);
  }
  .pq-redesign-root .nb-entry .nb-user-text p { margin: 0; }

  /* Photo caveat — small muted "skipped/extra" addendum */
  .pq-redesign-root .nb-entry .nb-photo-caveat {
    font-size: 11px;
    color: var(--pq-muted);
    background: transparent;
    border: none;
    padding: 8px 0 0 0;
    margin: 0;
    line-height: 1.45;
    font-family: var(--pq-sans);
  }
  .pq-redesign-root .nb-entry .nb-photo-caveat p { margin: 0; }
  .pq-redesign-root .nb-entry .nb-photo-caveat strong { color: var(--pq-ink-2); }

  /* Weather kind — small muted prose, no border, no bullet */
  .pq-redesign-root .nb-entry.weather {
    border-bottom: 1px solid var(--pq-line);
    padding: 8px 0;
  }
  /* Consecutive weather rows pile up at the bottom of the stream
     (one auto-generated entry per future day).  Squash them visually
     when stacked so the routine forecast doesn't dominate the log. */
  .pq-redesign-root .nb-entry.weather + .nb-entry.weather {
    padding-top: 2px;
    border-top: none;
  }
  .pq-redesign-root .nb-entry.weather + .nb-entry.weather .nb-ts,
  .pq-redesign-root .nb-entry.weather + .nb-entry.weather .nb-who {
    /* The author/timestamp on stacked weather rows just repeats the
       same auto-generated tag — drop it on adjacent rows so the
       reader's eye doesn't have to skim three identical chrome
       blocks. */
    opacity: 0.55;
  }
  .pq-redesign-root .nb-entry .nb-weather-text {
    font-size: 12px;
    color: var(--pq-muted);
    line-height: 1.5;
    background: transparent;
    border: none;
    padding: 0;
    font-style: normal;
    font-family: var(--pq-sans);
    display: block;
  }
  /* Weather entries leading the row with a small glyph.  We can't
     change the data flow (server-side prose), but a leading "✦" gives
     the eye a single visual anchor across stacked rows. */
  .pq-redesign-root .nb-entry.weather .nb-weather-text::before {
    content: "✦ ";
    color: var(--pq-blue, var(--pq-muted));
    margin-right: 2px;
  }
  .pq-redesign-root .nb-entry .nb-weather-text svg { display: none; }
  .pq-redesign-root .nb-entry .nb-weather-text span {
    font-style: normal;
    color: inherit;
  }

  /* Action kind — green-checked mono pill */
  .pq-redesign-root .nb-entry .nb-action {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    padding: 4px 10px;
    background: var(--pq-bg-2);
    border-radius: 4px;
    border: none;
    color: var(--pq-ink);
    font-family: var(--pq-mono);
    line-height: 1.3;
    margin: 0;
  }
  .pq-redesign-root .nb-entry .nb-action::before {
    content: "✓";
    color: var(--pq-green);
    font-weight: 600;
  }
  .pq-redesign-root .nb-entry .nb-action p { margin: 0; display: inline; }

  /* Question (ask) kind — italic with ink-coloured rule */
  .pq-redesign-root .nb-entry .nb-question {
    font-size: 14px;
    color: var(--pq-ink);
    font-style: italic;
    border-left: 2px solid var(--pq-ink);
    padding-left: 12px;
    background: transparent;
    margin: 0;
    line-height: 1.45;
    font-family: var(--pq-serif);
  }

  /* Assistant reply (answer) kind — surface card */
  .pq-redesign-root .nb-entry .nb-body {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: 6px;
    padding: 12px 14px;
    margin: 0;
    color: var(--pq-ink-2);
    font-size: 12px;
    line-height: 1.55;
    font-family: var(--pq-sans);
  }
  .pq-redesign-root .nb-entry .nb-body > *:first-child { margin-top: 0; }
  .pq-redesign-root .nb-entry .nb-body > *:last-child  { margin-bottom: 0; }
  .pq-redesign-root .nb-entry .nb-body p {
    font-size: 12px;
    color: var(--pq-ink-2);
    margin: 0 0 8px 0;
    line-height: 1.55;
  }
  .pq-redesign-root .nb-entry .nb-body p:last-child { margin-bottom: 0; }
  .pq-redesign-root .nb-entry .nb-body p:first-child {
    font-size: 13px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--pq-ink);
  }
  .pq-redesign-root .nb-entry .nb-body ul,
  .pq-redesign-root .nb-entry .nb-body ol {
    margin: 0 0 8px 0;
    padding-left: 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .pq-redesign-root .nb-entry .nb-body ul:last-child,
  .pq-redesign-root .nb-entry .nb-body ol:last-child { margin-bottom: 0; }
  .pq-redesign-root .nb-entry .nb-body li {
    font-size: 12px;
    color: var(--pq-ink-2);
    line-height: 1.5;
  }
  .pq-redesign-root .nb-entry .nb-body code {
    font-family: var(--pq-mono);
    font-size: 11px;
    background: var(--pq-bg-2);
    padding: 1px 4px;
    border-radius: 3px;
  }
  .pq-redesign-root .nb-entry .nb-body strong { color: var(--pq-ink); font-weight: 600; }

  /* Image entry — keep nb-image but tighten and round corners */
  .pq-redesign-root .nb-entry .nb-image {
    max-width: 320px;
    border-radius: 4px;
    border: 1px solid var(--pq-line);
    margin: 0;
  }

  /* Eyebrow + headline row above entries — already styled via .pq-day-eyebrow / .pq-day-headline */

  /* "Today's entries · N logged" section label — already rendered with
     class="nb-section-label" inside next_steps.html.  Restyle to match
     Joel's pq-eyebrow directly above a divider. */
  .pq-redesign-root .pq-today-main .nb-section-label {
    font-family: var(--pq-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 500;
    color: var(--pq-muted);
    margin: 24px 0 8px 0;
    padding: 0;
    border: none;
    background: transparent;
  }

  /* Hide the per-entry × delete button on desktop until hover, to keep
     the editorial feel (mock has no delete button visible at rest). */
  .pq-redesign-root .nb-entry .nb-delete {
    opacity: 0;
    transition: opacity 120ms ease;
  }
  .pq-redesign-root .nb-entry:hover .nb-delete {
    opacity: 0.6;
  }
  .pq-redesign-root .nb-entry .nb-delete:hover { opacity: 1; }


  /* ── Phase 6.4: summary inner sections (match summary.jsx) ──
     The mobile torn-yellow-pad notepad design (.wk-insights) is
     replaced on desktop with Joel's flat cream card.  Prose
     typography is harmonised to the redesign tokens. */

  .pq-redesign-root .wk-insights {
    /* Override the torn-pad treatment with Joel's flat cream card */
    background-color: #f3eedb !important;
    background-image: none !important;
    border: 1px solid #e7dfbe;
    border-radius: 6px;
    padding: 20px 22px !important;
    margin: 16px 0 36px !important;
    max-width: none !important;
    box-shadow: none !important;
  }
  .pq-redesign-root .wk-insights::before,
  .pq-redesign-root .wk-insights::after {
    display: none !important;
  }
  /* Prose inside the cream card: preserve the editorial voice from the
     original notepad design — italic serif h2 as section markers, plain
     body paragraphs.  Override !important from the legacy block. */
  .pq-redesign-root .wk-insights .prose {
    font-family: var(--pq-serif) !important;
    font-size: 14.5px !important;
    line-height: 1.6 !important;
    color: var(--pq-ink-2) !important;
  }
  .pq-redesign-root .wk-insights .prose h1,
  .pq-redesign-root .wk-insights .prose h2 {
    font-family: var(--pq-serif) !important;
    font-style: italic !important;
    font-size: 16px !important;
    font-weight: 500 !important;
    line-height: 1.3 !important;
    color: var(--pq-red) !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
    margin: 14px 0 4px 0 !important;
  }
  .pq-redesign-root .wk-insights .prose h1:first-child,
  .pq-redesign-root .wk-insights .prose h2:first-child { margin-top: 0 !important; }
  .pq-redesign-root .wk-insights .prose h3 {
    font-family: var(--pq-mono) !important;
    font-size: 10.5px !important;
    text-transform: uppercase !important;
    letter-spacing: 0.12em !important;
    color: var(--pq-muted) !important;
    font-weight: 500 !important;
    margin: 12px 0 4px 0 !important;
  }
  .pq-redesign-root .wk-insights .prose p {
    margin: 0 0 10px 0 !important;
    line-height: 1.6 !important;
    font-size: 14.5px !important;
    color: var(--pq-ink-2) !important;
    font-family: var(--pq-serif) !important;
  }
  .pq-redesign-root .wk-insights .prose p:last-child { margin-bottom: 0 !important; }
  .pq-redesign-root .wk-insights .prose ul,
  .pq-redesign-root .wk-insights .prose ol {
    margin: 4px 0 10px 0 !important;
    padding-left: 22px !important;
  }
  .pq-redesign-root .wk-insights .prose li {
    margin: 2px 0 !important;
    font-family: var(--pq-serif) !important;
    font-size: 14.5px !important;
    line-height: 1.6 !important;
    color: var(--pq-ink-2) !important;
  }
  .pq-redesign-root .wk-insights .prose strong {
    color: var(--pq-ink) !important;
    font-weight: 600 !important;
  }
  .pq-redesign-root .wk-insights .prose em { font-style: italic !important; }
  .pq-redesign-root .wk-insights .prose code {
    font-family: var(--pq-mono) !important;
    font-size: 12px !important;
    background: rgba(184, 65, 44, 0.06) !important;
    padding: 1px 4px !important;
    border-radius: 3px !important;
  }
  .pq-redesign-root .wk-insights .prose blockquote {
    border-left: 2px solid var(--pq-amber) !important;
    padding-left: 12px !important;
    margin: 10px 0 !important;
    color: var(--pq-ink-2) !important;
    font-style: italic !important;
  }
  .pq-redesign-root .wk-insights-footer {
    border-top: 1px dashed #d5cb9b !important;
    margin-top: 14px !important;
    padding-top: 12px !important;
    font-family: var(--pq-mono);
    font-size: 10px;
    color: var(--pq-muted);
  }

  /* Spotlight headline — the "Temp has been creeping up..." h2 above the card.
     Existing wk-spotlight uses ink/serif but at the wrong family. */
  .pq-redesign-root .wk-spotlight {
    border-top: none;
    border-bottom: none;
    padding: 0;
    margin: 0 0 18px 0;
  }
  .pq-redesign-root .wk-spotlight .kicker {
    font-family: var(--pq-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--pq-muted);
    margin-bottom: 6px;
    font-weight: 500;
  }
  body.pq-redesign-root .wk-spotlight .head,
  body.pq-redesign-root .wk-spotlight h2,
  body.pq-redesign-root .wk-spotlight .headline {
    font-family: var(--pq-serif) !important;
    font-size: 24px !important;
    font-weight: 500 !important;
    line-height: 1.15 !important;
    letter-spacing: -0.015em !important;
    color: var(--pq-ink) !important;
    margin: 4px 0 10px !important;
  }
  body.pq-redesign-root .wk-spotlight .body,
  body.pq-redesign-root .wk-spotlight .lede,
  body.pq-redesign-root .wk-spotlight .subhead {
    font-size: 14px !important;
    color: var(--pq-ink-2) !important;
    line-height: 1.6 !important;
    font-family: var(--pq-sans) !important;
    max-width: none !important;
  }

  /* Section labels above each section — match Joel's pq-eyebrow */
  .pq-redesign-root .wk-section-label {
    font-family: var(--pq-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--pq-muted);
    font-weight: 500;
    margin: 28px 0 10px;
  }

  /* ── Phase 6.5: measurements polish (match measurements.jsx) ── */

  /* Stat strip in the editorial header — labels need eyebrow style.
     Already added .pq-eyebrow rule above; this just ensures the
     numeric value is properly mono. */
  .pq-redesign-root .pq-meas-head .pq-num { font-feature-settings: "tnum", "zero"; }

  /* Pill row → harmonise to Joel's pq-chip data-state pattern.
     The .nb-pill class shouldn't apply on desktop; convert the pills
     to inline-flex chip buttons matching the mock. */
  .pq-redesign-root .nb-pill-row .nb-pill {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 4px 12px;
    height: 28px;
    border-radius: 999px;
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    font-family: var(--pq-sans);
    font-size: 13px;
    color: var(--pq-ink-2);
    text-decoration: none;
  }
  .pq-redesign-root .nb-pill-row .nb-pill .name {
    font-weight: 500;
    letter-spacing: 0;
    color: inherit;
  }
  .pq-redesign-root .nb-pill-row .nb-pill .v {
    font-family: var(--pq-mono);
    font-size: 12px;
    color: var(--pq-muted);
    font-feature-settings: "tnum", "zero";
  }
  .pq-redesign-root .nb-pill-row .nb-pill[aria-current="true"] {
    /* --brand-droplet fill + --brand-deep text matches the segmented
       zoom — the active filter is a brand moment, not a defaulted
       black "primary action". */
    background: var(--brand-droplet);
    color: var(--brand-deep);
    border-color: var(--brand-droplet);
  }
  .pq-redesign-root .nb-pill-row .nb-pill[aria-current="true"] .v { color: color-mix(in srgb, var(--brand-deep) 65%, transparent); }
  .pq-redesign-root .nb-pill-row .nb-pill[aria-current="true"] .name { color: var(--brand-deep); }
  .pq-redesign-root .nb-pill-row .nb-pill .dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    margin-right: 2px;
  }

  /* Hero metric card — wrap the .nb-hero block in Joel's surface card */
  .pq-redesign-root .nb-hero {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: 6px;
    overflow: hidden;
    padding: 0;
    margin-bottom: 28px;
  }
  .pq-redesign-root .nb-hero .label {
    font-family: var(--pq-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--pq-muted);
    font-weight: 500;
    padding: 18px 24px 0;
  }
  .pq-redesign-root .nb-hero .value-row {
    padding: 0 24px;
    margin: 4px 0 6px;
    align-items: baseline;
  }
  .pq-redesign-root .nb-hero .v {
    font-family: var(--pq-mono);
    font-size: 44px;
    font-weight: 500;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--pq-ink);
  }
  .pq-redesign-root .nb-hero .u {
    font-family: var(--pq-mono);
    font-size: 14px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .nb-hero .ideal {
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .nb-hero .delta {
    padding: 0 24px 12px;
    margin-bottom: 0;
    border-bottom: 1px solid var(--pq-line);
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .nb-hero .chart-wrap {
    padding: 16px 24px 20px;
    min-height: 220px;
  }
  .pq-redesign-root .nb-hero .chart-wrap svg {
    width: 100% !important;
    height: 220px !important;
    display: block;
  }

  /* Small multiples — convert nb-spark-grid 2-up → Joel's 4-up cards */
  .pq-redesign-root .nb-spark-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    border-top: none;
    padding-top: 0;
    margin-top: 0;
  }
  @media (max-width: 1280px) {
    .pq-redesign-root .nb-spark-grid {
      grid-template-columns: repeat(3, 1fr);
    }
  }
  .pq-redesign-root .nb-spark {
    background: var(--pq-surface);
    border: 1px solid var(--pq-line);
    border-radius: 6px;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .pq-redesign-root .nb-spark .head {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin-bottom: 0;
  }
  .pq-redesign-root .nb-spark .name {
    font-family: var(--pq-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--pq-muted);
    font-weight: 500;
  }
  .pq-redesign-root .nb-spark .v {
    font-family: var(--pq-mono);
    font-size: 22px;
    font-weight: 500;
    color: var(--pq-ink);
    line-height: 1.1;
  }
  .pq-redesign-root .nb-spark .u {
    font-family: var(--pq-mono);
    font-size: 11px;
    color: var(--pq-muted);
  }
  .pq-redesign-root .nb-spark svg {
    width: 100% !important;
    height: 36px !important;
  }

  /* ── r2 fixes (summary + measurements layout polish) ───────────── */

  /* #1 Editorial headline orphans — balance lets the browser
     redistribute words so "Seven weeks of pool." doesn't drop the
     last word onto its own line.  The legacy mobile .nb-weeks-h1 /
     .nb-all-h1 also gets the rule (in their inline <style>). */
  .pq-redesign-root .pq-day-headline,
  .pq-redesign-root .nb-all-h1,
  .pq-redesign-root .nb-weeks-h1,
  .pq-redesign-root .wk-spotlight .head { text-wrap: balance; }

  /* #5 Summary TOC — give every item the same gutter so the active
     bar lives in space already reserved.  Without this the active
     item shifted -13px to host its border and unselected items sat
     ~12px deeper, which read as accidental nesting.  Now: parent
     drops its own border-left, each child renders a 2px transparent
     left border that turns ink-coloured when active. */
  .pq-redesign-root .pq-summary-toc {
    border-left: none;
    padding-left: 0;
  }
  .pq-redesign-root .pq-summary-toc a {
    padding-left: 12px;
    border-left: 2px solid var(--pq-line);
  }
  .pq-redesign-root .pq-summary-toc a[data-active="true"] {
    margin-left: 0;
    padding-left: 12px;
    border-left-color: var(--pq-ink);
  }

  /* #6 Right-rail Ask suggestions wrap onto two lines at 1024 because
     the rail is only ~240px wide.  Below 1100 we shrink the chip
     type-size + padding so the most common questions still fit on
     one line; below 1024 the rail is hidden entirely (already). */
  @media (max-width: 1099px) {
    .pq-redesign-root .pq-summary-ask-suggestions a {
      font-size: 10.5px;
      height: 24px;
      padding: 0 8px;
      letter-spacing: 0;
    }
    .pq-redesign-root .pq-summary-ask-suggestions a span {
      display: none;
    }
  }

  /* #7 Active filter chip on /measurements picked up the global
     `a:hover { text-decoration: underline }` rule from app.css.
     Belt + braces: pin text-decoration: none on every chip state.
     Also covers the legacy non-redesign root, see measurements.html
     inline <style>. */
  .pq-redesign-root .nb-pill,
  .pq-redesign-root .nb-pill:hover,
  .pq-redesign-root .nb-pill:focus,
  .pq-redesign-root .nb-pill:visited,
  .pq-redesign-root .nb-pill[aria-current="true"],
  .pq-redesign-root .nb-pill[aria-current="true"]:hover {
    text-decoration: none;
  }

  /* #8 Hierarchy fragmentation on /measurements — non-active metrics
     used to render a card with name+value stacked above a 36px
     sparkline, leaving a chunky empty band when the metric was
     mostly flat. Tighten to a single horizontal row: name + value on
     the left, sparkline filling the right.  Same density end-to-end. */
  .pq-redesign-root .nb-spark-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
  }
  @media (max-width: 1280px) {
    .pq-redesign-root .nb-spark-grid {
      grid-template-columns: repeat(2, 1fr);
    }
  }
  .pq-redesign-root .nb-spark {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 10px 14px;
    min-height: 48px;
  }
  .pq-redesign-root .nb-spark .head {
    flex: 0 0 auto;
    flex-direction: row;
    align-items: baseline;
    gap: 8px;
  }
  .pq-redesign-root .nb-spark .name {
    font-size: 10px;
  }
  .pq-redesign-root .nb-spark .v {
    font-size: 16px;
  }
  .pq-redesign-root .nb-spark svg {
    flex: 1 1 auto;
    width: auto !important;
    height: 28px !important;
    max-width: 60%;
  }
}


/* ── shared admin chrome ────────────────────────────────────────────
   Each admin_*.html template defines its own .usage-shell / .usage-page
   styles inline; the rules below tweak shared concerns (max-width on
   wide viewports, scroll-fade hints on overflow tables, mobile-collapse
   for the dwell breakdowns) without duplicating per-template CSS. */

/* Wider admin column on desktop. The inline `max-width: var(--col-wide)`
   in each template is 920px, which leaves ~280px of dead margin on a
   1440 viewport. Bump it. */
@media (min-width: 1024px) {
  .usage-page {
    max-width: 1280px !important;
  }
}

/* Right-edge fade so users can tell a table scrolls horizontally. The
   gradient sits on the wrapper so it stays visible while the inner table
   pans. JS-free; just a visual hint. Only shown below 1024px — at wider
   viewports the admin column is 1280px and tables (min-width 520-760px)
   fit, so the fade would be a false signal. */
.usage-table-scroll {
  position: relative;
}
@media (max-width: 1023px) {
  .usage-table-scroll::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 36px;
    pointer-events: none;
    /* Stronger gradient (paper → solid paper) than the previous near-
       transparent one, so the fade actually reads as a scroll affordance
       instead of a smudge. The 0.95 stop makes the right edge clearly
       solid; the 0 stop on the left lets the underlying table cell text
       fade out instead of hard-clipping at a glyph boundary. */
    background: linear-gradient(to right, rgba(251, 250, 247, 0) 0%, var(--paper) 70%, var(--paper) 100%);
  }
}

/* Dwell breakdowns are noisy on phones — collapse Channel / Campaign /
   Device / OS / CTA under <details> disclosures on narrow viewports.
   On wider viewports the <details> opens and the marker hides so the
   markup looks like a flat section. */
.usage-section.collapsible > details > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.usage-section.collapsible > details > summary::-webkit-details-marker {
  display: none;
}
.usage-section.collapsible > details > summary > h2 {
  display: inline-block;
  margin-right: 6px;
}
.usage-section.collapsible > details > summary::after {
  content: "▸";
  color: var(--ink-3);
  font-size: 11px;
  display: inline-block;
  transition: transform 0.15s;
}
.usage-section.collapsible > details[open] > summary::after {
  transform: rotate(90deg);
}
@media (min-width: 881px) {
  /* Above the breakpoint we don't need the disclosure UI — the inline
     script in admin_dwell.html sets the `open` attribute, so the body
     is visible. Just hide the affordance so the section reads flat. */
  .usage-section.collapsible > details > summary { cursor: default; }
  .usage-section.collapsible > details > summary::after { display: none; }
}

/* Sandbox session card: keep UA on a single ellipsised line so the
   event timeline below it stays the focus. The inline rule already
   does this for `.session-head .ua`; this guards against the inner
   grid column expanding past the card boundary, which makes
   `max-width: 100%` resolve to a wider value than the card. */
.session-card .session-head { min-width: 0; }
.session-card .session-head > div { min-width: 0; }
.session-card .session-head .ua,
.session-card .ua {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Render sandbox events as inline chips so the kind sequence
   (open → submit → llm_reply) is scannable across one row instead
   of stacked three-column rows. The inline ol still works as a
   fallback if a card opts out. */
.session-card .session-events.chips ol {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.session-card .session-events.chips li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  font-family: var(--type-num);
  font-size: 11px;
  color: var(--ink-2);
  grid-template-columns: none;
}
.session-card .session-events.chips li .kind {
  color: var(--brand);
  font-weight: 500;
}
.session-card .session-events.chips li .ts {
  color: var(--ink-3);
}
.session-card .session-events.chips li .payload {
  color: var(--ink-3);
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Alerts list: third-card timestamp `05/0…` was clipping on the right
   on narrow viewports because the grid track held the timestamp at its
   intrinsic size while the message div had no `min-width: 0` to allow
   shrink. Below 520px stack timestamp under the body. */
@media (max-width: 520px) {
  .alerts-list li {
    grid-template-columns: 1fr !important;
  }
  .alerts-list li .ts {
    grid-column: 1;
    margin-top: 2px;
  }
  .alerts-list li .msg {
    min-width: 0;
  }
}

