/* Caltrack. Section 11: dark only, density over whitespace, one file. */

/* The merge checkbox is the only native control here and iOS renders it well
   under 20px. It arms an action that rewrites canonical_name on live entries,
   so it is worth being able to hit deliberately. */
input[type="checkbox"].pick {
    width: 22px;
    height: 22px;
    margin: 11px 0;      /* 22 + 11 + 11 = a 44px row to aim at */
    accent-color: var(--green);
}

:root {
    /* Navy, sampled from the owner's own reference screenshot on 22 Aug 2026 —
       measured, not guessed. --dim/--dimmer/--border were checked against
       these (contrast ratios in the plan's Task A report) rather than
       assumed to still read once the background stopped being pure grey. */
    --bg:      #0f131b;
    --card:    #1c2330;
    --border:  #2a3242;   /* navy-tinted; mirrored in static/app.js's C.border */
    --text:    #e5e5e5;
    --dim:     #959595;   /* 5.26:1 on --card; #8a8a8a was 4.57, AA by 0.07 */
    /* --dimmer (#5a5a5a) was retired 25 Aug 2026. It sat at 2.29:1 on
       --card, well under the 4.5:1 text floor, and there is no value that
       is both meaningfully dimmer than --dim and readable — 4.5:1 lands at
       about #8a8a8a, which is --dim. Everything it coloured was text
       somebody has to read: the Sign out control, and the empty-state rows.
       Those use --dim now, and "less important" is carried by size and
       position instead of by fading text below legibility. */
    /* Interactive surfaces, on the navy ramp. These were neutral greys
       (#232323, #3d3d3d, #262626, #1f1f1f, #121212) repeated across a dozen
       rules — the same drift the note above records for the chart hairlines,
       and the reason a button read as warm against a navy card. Worse,
       #232323 sat at 1.00 contrast with --card: bordered buttons were
       distinguished from the card behind them by their 1.23:1 border alone.
       Every one is now navy at a deliberate step, and each step is more
       separated than the grey it replaced, not less. */
    --surface: #252e40;   /* raised: buttons, the active range/sort toggle */
    --recess:  #141a26;   /* sunken: text inputs, selects, textareas */
    --track:   #232b3c;   /* the unfilled part of a bar */
    --hover:   #222a3a;   /* a row or meal under the cursor */
    --line-strong: #3c4761; /* a border on hover, or on an active toggle */
    --green:   #22c55e;
    /* --green at low alpha, for the calorie band's shaded zone on the daily
       log cards — the same visual language as the dashboard calorie chart's
       BAND_TINT in static/app.js (rgba(34,197,94,.10)), which computes an
       rgba string from --green at runtime; CSS has no such helper here, so
       this is a second literal of the same colour, kept a shade stronger
       (.18) because it sits over a solid bar rather than a chart's empty
       background. */
    --band-tint: rgba(34, 197, 94, 0.18);
    --red:     #f26969;   /* 5.25:1 on --card; #ef4444 failed AA at 4.19 */
    --amber:   #f59e0b;
    --blue:    #5894f7;   /* 5.25:1 on --card; #3b82f6 failed AA at 4.29 */
    --teal:    #14b8a6;
    --orange:  #f97316;

    --pad:     16px;
    --gap:     12px;
    --radius:  12px;

    /* Reading text; the 430px band below raises both once (labels/badges stay literal). */
    --font-base: 14px;
    --font-sm:   13px;
}

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

/* Any author `display` beats the UA stylesheet's `[hidden]`, whatever the
   specificity, so every class that sets display silently un-hides itself.
   That has now happened twice — .edit-panel on the day page, then
   .daycard-meal-items, which shipped every meal expanded. One rule here
   rather than one per class, because the next one would be missed too. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 400 var(--font-base)/1.45 Inter, -apple-system, BlinkMacSystemFont,
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    /* Tabular figures everywhere. Every number on this page sits in a column
       or a chart label, and proportional digits make them jump as they tick. */
    font-variant-numeric: tabular-nums;
    padding: env(safe-area-inset-top) env(safe-area-inset-right)
             env(safe-area-inset-bottom) env(safe-area-inset-left);
}

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }

main {
    max-width: 900px;
    margin: 0 auto;
    padding: 0 var(--gap) 48px;
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

/* ------------------------------------------------------------- top bar */

.topbar {
    max-width: 900px;
    margin: 0 auto;
    padding: 20px var(--gap) var(--gap);
}
.topbar-main {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap);
    flex-wrap: wrap;
}
.topbar h1 { font-size: 20px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.topbar nav { display: flex; gap: 14px; font-size: var(--font-sm); }
.topbar nav a { color: var(--dim); display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; } /* 44x44 tap target */
.topbar nav a.on { color: var(--text); }

/* the sign-out form has to sit in the nav row like the links either side */
.topbar nav .signout { display: inline; margin: 0; }
button.linklike {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-size: var(--font-sm);
    color: var(--dim);          /* was --dimmer: 2.29:1, unreadable */
    cursor: pointer;
}
button.linklike:hover { text-decoration: underline; border: 0; }

.summary { color: var(--dim); font-size: var(--font-sm); margin: 6px 0 0; }
.summary strong { color: var(--text); font-weight: 500; }

.pills { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 12px;
    color: var(--dim);
}
.pill strong { color: var(--text); font-weight: 500; }
.pill.streak strong { color: var(--green); }
.pill.streak.cold strong { color: var(--dim); }
/* Jump To, header, day.php prev/next. 32px, not the 44x44 tap-target
   guideline: on the owner's phone the Jump To row is a dozen pills and 44px
   spent three rows of screen on navigation before any data. One user, one
   thumb, and a mis-tap costs an anchor jump. */
a.pill { min-height: 32px; min-width: 32px; }

/* ------------------------------------------------------------- jump to */

/* Reuses .pill — one definition of that look — rather than adding its own
   horizontal padding, which would double up on <main>'s. Wraps as needed. */
.jumpto {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}
.jumpto a.pill:hover { color: var(--text); border-color: var(--dim); }
/* The 30/60/90 range rides the same row, pushed to the right edge; on a
   narrow screen it wraps to its own line and stays right-aligned. */
.jumpto .range-toggle { margin-left: auto; }

/* A jump-to link must not land with its heading under the header. 126px ~=
   the 390px header's height (14px pad + title/nav ~32, since the nav links'
   min-height sets the row's height, not their 14px text + summary ~25 + one
   pill row ~32 + 10px pad). Not position:sticky today, so nothing actually
   overlaps yet — a cheap buffer against the day it becomes one. Tracks
   a.pill's min-height: was 138px when that was 44px. */
section.card[id] { scroll-margin-top: 126px; }

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

.card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--pad);
}
/* One rule for every card heading, whether it sits directly under .card or
   inside .card-head. The .card > h2 version used to be 11px uppercase dim —
   the smallest, faintest text on the card — and .card-head h2 only set a
   margin, so the two kinds of heading had drifted apart. */
.card h2 {
    font-size: 15px;
    color: var(--text);
    font-weight: 600;
    margin: 0 0 12px;
}
.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap);
    margin-bottom: 12px;
}
.card-head h2 { margin: 0; }
/* A row of controls: a button beside its status text. .spaced hangs it below
   what precedes it. */
.btn-row { display: flex; gap: 8px; align-items: center; }
.btn-row.spaced { margin-top: 12px; flex-wrap: wrap; }
/* The badge under the Today card's figures. */
.badge-row { margin-top: 8px; }
/* Explanation folded away from a legend: how a thing is measured, not what
   the colours mean. */
details.more { margin-top: 8px; font-size: 11px; color: var(--dim); }
details.more summary { cursor: pointer; width: fit-content; }
details.more summary:hover { color: var(--text); }
.legend { font-size: 11px; color: var(--dim); }
/* A legend as a paragraph explains the thing above it, so it hangs below by
   default; .above flips it for the ones that introduce a chart instead.
   These two margins used to be written inline on all nineteen of them, and
   had drifted to three values (8px, 10px, 12px) for what is one decision —
   the same legend under two charts sat 2px differently apart. */
p.legend, p.notice { margin: 8px 0 0; }
p.legend.above, p.notice.above { margin: 0 0 8px; }
.legend .g { color: var(--green); }
.legend .r { color: var(--red); }
/* The "computed from the macros" mark on a kcal figure (day.php). Dim on
   purpose: it is a note about a number, never a warning about one. */
.derived { color: var(--dim); margin-left: 3px; cursor: help; }

/* The macro split, on the foods leaderboard and in the line that explains it.
   One definition of the three colours: they were hardcoded hex in foods.php
   while the same values already existed as variables here. */
.mp { color: var(--blue); }
.mc { color: var(--teal); }
.mf { color: var(--orange); }
.ma { color: var(--amber); }
.mg { color: var(--green); }
.mr { color: var(--red); }
/* Three short percentages that mean nothing broken across lines. The table
   already scrolls sideways inside .scroll-x when it has to, which is the
   right way for this to give way on a narrow screen. */
td.split { white-space: nowrap; }

/* ----------------------------------------------------------- today card */

.today-grid {
    display: flex;
    gap: var(--pad);
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
}
.today-bars { flex: 1 1 260px; display: flex; flex-direction: column; gap: 14px; }

.bar-label {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: var(--dim);
    margin-bottom: 5px;
}
.bar-label b { color: var(--text); font-weight: 500; }
/* The label that reads BELOW a bar. Written inline on each of them until
   30 Aug 2026, at 5px on the Today card and 8px on the daily-log cards for
   the same relationship — and repeated into the payload once per day card. */
.bar + .bar-label { margin-top: 5px; }
.daycard .bar + .bar-label { margin-top: 8px; }
.bar {
    height: 8px;
    background: var(--track);
    border-radius: 999px;
    overflow: hidden;
}
.bar span { display: block; height: 100%; border-radius: 999px; }
.bar span.green { background: var(--green); }
.bar span.red   { background: var(--red); }
.bar span.blue  { background: var(--blue); }

.today-side { text-align: right; font-size: 12px; color: var(--dim); }
.today-side .big { font-size: 22px; color: var(--text); display: block; line-height: 1.2; }

.badge {
    display: inline-block;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 2px 7px;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--dim);
}
.badge.LIFTING { color: var(--blue);   border-color: #24406e; }
.badge.CARDIO  { color: var(--orange); border-color: #6b3a17; }
.badge.WALK    { color: var(--teal);   border-color: #14544d; }

.meal {
    display: inline-block;
    border-radius: 5px;
    padding: 2px 6px;
    font-size: 10px;
    letter-spacing: 0.05em;
    background: var(--surface);
    color: var(--dim);
}

/* -------------------------------------------------------------- charts */

.chart-wrap { position: relative; height: 190px; }
.chart-wrap.short { height: 150px; }

.range-toggle { display: flex; gap: 4px; }
.range-toggle button {
    background: none;
    border: 1px solid var(--border);
    color: var(--dim);
    border-radius: 6px;
    padding: 3px 9px;
    font: inherit;
    font-size: 11px;
    cursor: pointer;
}
.range-toggle button.on { color: var(--text); border-color: var(--line-strong); background: var(--surface); }

/* --------------------------------------------------------------- table */

table { width: 100%; border-collapse: collapse; font-size: var(--font-sm); }
th {
    text-align: left;
    /* 11px, not 10: these headers are what separate "Protein/100g" (grams)
       from "% of kcal" (calorie share), and reading them as the same kind
       of number is a mistake the table has already caused once. */
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--dim);
    font-weight: 500;
    padding: 0 8px 8px 0;
    white-space: nowrap;
}
th a { color: inherit; }
th a.on { color: var(--text); }
td {
    padding: 7px 8px 7px 0;
    border-top: 1px solid var(--border);
    vertical-align: middle;
}
tr.blank td { color: var(--dim); }
.num { text-align: right; }
.ok  { color: var(--green); }
.no  { color: var(--red); }
.dim { color: var(--dim); }
.warn { color: var(--amber); }

/* a small inline bar, for protein density in the food table */
.minibar {
    display: inline-block;
    width: 46px;
    height: 5px;
    background: var(--track);
    border-radius: 999px;
    overflow: hidden;
    vertical-align: middle;
}
.minibar span { display: block; height: 100%; background: var(--blue); }

.score { font-weight: 500; }
.score.green { color: var(--green); }
.score.amber { color: var(--amber); }
.score.red   { color: var(--red); }

.thumb {
    width: 34px; height: 34px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--border);
    display: block;
}

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

/* One inner box per day inside the "Daily log" section. --bg rather than
   --card so it reads as nested inside the outer card, not a sibling of it. */
.daycard {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px;
}
.daycard + .daycard { margin-top: var(--gap); }

.daycard-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 10px;
}
.daycard-head-left { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.daycard-date { font-weight: 500; }
.daycard-metric { font-size: 12px; }
.daycard-metric .dim:first-child { margin-right: 3px; }

.daycard-kcal { font-size: 18px; font-weight: 600; text-align: right; white-space: nowrap; }
.daycard-kcal .dim { font-size: 12px; font-weight: 400; }

/* The deficit-goal line, positioned inside .bar — hence position:relative,
   scoped here so it cannot bleed into the Today card's plain bars. */
.bar { position: relative; }
.bar .target-marker {
    position: absolute;
    top: 0; bottom: 0;
    width: 2px;
    background: var(--text);
    opacity: 0.6;
}
/* The calorie band, shaded rather than lined — see lib/daycard.php. Its
   right edge is always the bar's own right edge, because the bar is scaled
   to the top of the band (calorie_high), the same convention the protein
   bar already uses for its own zone top; only `left` varies per day. Flat
   corners rather than the pill shape `.bar span` gets everywhere else, so a
   wide zone doesn't round like a fill bar does. */
.bar .band-zone {
    position: absolute;
    top: 0; bottom: 0; right: 0;
    background: var(--band-tint);
    border-radius: 0;
}

.daycard-summary { font-size: 12px; color: var(--dim); margin: 10px 0; }

.daycard-sort {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    margin-bottom: 8px;
}
.sort-toggle {
    background: none;
    border: 1px solid var(--border);
    color: var(--dim);
    border-radius: 6px;
    padding: 3px 8px;
    font: inherit;
    font-size: 11px;
    cursor: pointer;
    /* Not a tap target the sitewide button rule's 44x44 is for (Finding 6,
       review 22 Aug 2026): it sits beside an 11px "Sort:" label on every day
       card, and the class selector here already outranks the element
       selector on `button, .button`, so this alone is enough to opt out —
       no !important needed. */
    min-height: 0;
    min-width: 0;
}
.sort-toggle.on { color: var(--text); border-color: var(--line-strong); background: var(--surface); }

.daycard-entries { display: flex; flex-direction: column; }

/* One row per meal, a link rather than a button: ingredients live behind
   day.php now, not an expander (removed deliberately). Four fixed lanes
   (reference screenshot, 22 Aug 2026): TYPE, name (wraps), density, macros.
   Four grid items in source order, one per column — no grid-area needed,
   unlike the three-lane version this replaced, which faked a fourth lane
   (the time) by spanning it under two columns on a second row. Here the
   name lane holds the label and the time as ordinary inline content, so
   only that lane wraps; the others are one short line each and stay at the
   top of whatever height the wrap gives the row.
   minmax(0, 1fr) not 1fr on the name: a grid track's default minimum is its
   content, so a long unbroken word would push the macros off the right
   edge at 440px. Type alone is a pixel guess — MEAL_TYPES (lib/store.php)
   is a closed five-word enum, BREAKFAST the longest — density and macros
   are max-content instead of a second guess with no browser to check it. */
.daycard-meal {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr) max-content max-content;
    column-gap: 10px;
    align-items: start;
    padding: 10px 0;
    border-top: 1px solid var(--border);
    color: inherit;
    min-height: 44px;
}
.daycard-meal:hover { background: var(--hover); }
/* Plain uppercase text here, not the rounded pill .meal still is in
   day.php's table — the reference shows a bare "LUNCH", no chip. Overridden
   in this context only; .meal itself stays a pill everywhere else. */
.daycard-meal .meal {
    display: block;
    background: none;
    border: 0;
    padding: 0;
    border-radius: 0;
    text-transform: uppercase;
}
.daycard-meal-label { min-width: 0; }
.daycard-meal .daycard-entry-meta { font-size: var(--font-sm); }
.daycard-meal .daycard-entry-density { white-space: nowrap; }
.daycard-meal .daycard-entry-macros {
    text-align: right;
    white-space: nowrap;
}

/* Landscape (956x440, the reference's clearer shot): widen the lanes, not
   the type — the type lane and the gaps between lanes grow; font sizes do
   not change here (that is the separate 430px reading-text breakpoint). */
@media (min-width: 700px) {
    .daycard-meal { grid-template-columns: 80px minmax(0, 1fr) max-content max-content; column-gap: 18px; }
    .daycard-meal .daycard-entry-density { padding-right: 10px; }
}

/* Its own scroller, never the body. Unconditional rather than the media-
   gated .scroll-x utility — a photo strip can overflow at any width. */
.daycard-photos {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    padding-bottom: 2px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.daycard-photos .thumb { width: 52px; height: 52px; flex: 0 0 auto; }


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

input[type=text], input[type=number], input[type=password], select, textarea {
    background: var(--recess);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font: inherit;
    padding: 8px 10px;
    width: 100%;
    font-variant-numeric: tabular-nums;
}
/* Keyboard focus, sitewide. Until 25 Aug 2026 the ONLY focused thing that
   changed appearance was a text input, and it changed to a 1px #3d3d3d
   outline — 1.45:1 against the card, which is to say invisible. Buttons,
   links, the range toggle and the merge checkboxes showed nothing at all,
   so tabbing through this site left no way to tell where you were.

   --blue is the one palette colour not already carrying a verdict: green is
   a hit, red a miss, amber a warning, and a focus ring must not read as any
   of those. 5.25:1 on --card, comfortably past the 3:1 that WCAG asks of a
   non-text indicator.

   :focus-visible, not :focus, so the ring appears for the keyboard and never
   for a thumb — the phone is where this app is actually used, and a ring
   that latched onto every tap would be noise on the platform that needs it
   least. */
:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

/* Hover/typing state stays distinct from focus: this is the "you are editing
   this field" cue, and the ring above is "the keyboard is here". */
input:focus, select:focus, textarea:focus { border-color: var(--dim); }
label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--dim); margin-bottom: 5px; }

button, .button {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    font: inherit;
    padding: 8px 14px;
    cursor: pointer;
    min-height: 44px; /* Apple's 44x44pt min, sitewide — every bordered button is a real <button> */
    min-width: 44px;
}
button:hover { border-color: var(--line-strong); }
button.primary { background: var(--green); border-color: var(--green); color: #06240f; font-weight: 500; }
button.danger  { color: var(--red); }
/* Not a tap target (Finding 6, review 22 Aug 2026): the alias table's ✕ is
   inline chrome in a narrow numeric column, and 44x44 widened that column
   on every row. .danger stays shared with the real Delete button on day.php,
   so the override is scoped to .unmerge alone, not to .danger. */
.unmerge { min-height: 0; min-width: 0; padding: 3px 8px; }

.field-row { display: flex; gap: var(--gap); flex-wrap: wrap; }
.field-row > div { flex: 1 1 130px; }
/* A field that takes the whole row — a description, or a row of buttons.
   The grid equivalent inside .edit-panel is .ef-wide. */
.field-row > div.wide { flex-basis: 100%; }

.error {
    color: var(--red);
    background: #2a1414;
    border: 1px solid #4a1f1f;
    border-radius: 8px;
    padding: 8px 10px;
    font-size: var(--font-sm);
}
.notice { color: var(--dim); font-size: var(--font-sm); }

/* --------------------------------------------------------------- login */

.login {
    max-width: 300px;
    margin: 18vh auto 0;
    display: flex;
    flex-direction: column;
    gap: var(--gap);
    padding: 0 var(--gap);
}
.login h1 { font-size: 22px; font-weight: 600; margin: 0 0 4px; text-align: center; }
.login form { display: flex; flex-direction: column; gap: 8px; }

/* ------------------------------------------------- phone-width behaviour */

/* Up to 560px, any phone: the leaderboard's nine columns keep scrolling
   sideways in their own card; the day list has no .wide and just drops to
   four columns instead, since those fit. */
@media (max-width: 560px) {
    .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .scroll-x table { min-width: 100%; }
    .scroll-x table.wide { min-width: 560px; }
    .hide-sm { display: none; }
}

/* 430px+ (440 is the iPhone 17 Pro Max): raise the reading-text properties —
   14/13px is small on a 6.9in screen. --pad/--gap need no override; :root's
   16/12px default already is the roomy spacing the floor below turns down. */
@media (min-width: 430px) {
    :root { --font-base: 16px; --font-sm: 14px; }
}

/* Below 430px, the floor: the exact 390px treatment this stylesheet was
   built for. Used to be one `max-width:560px` query, so a 440px phone got a
   small phone's padding/header/charts too — the bug this task fixes.
   429.98px, not 429px (Finding 7, review 22 Aug 2026): browser zoom can land
   a layout width anywhere, including a fraction, and 429px/430px as a pair
   left 429.1-429.99 matching neither band. */
@media (max-width: 429.98px) {
    :root { --pad: 13px; --gap: 10px; }
    .topbar { padding-top: 14px; }
    .topbar h1 { font-size: 18px; }
    .topbar nav { gap: 12px; font-size: 12px; }
    .today-side { text-align: left; } /* stacked under the bars here; fits beside them from 430px */
    .chart-wrap { height: 165px; }
}

/* -------------------------------------------------- entry edit, day.php */

/* Deliberately its own list, not the entries table's last column, so
   Edit/Delete stay reachable without the sideways scroll .scroll-x needs. */
/* Tapping an entry row opens its edit panel, which is the row directly
   beneath it. This replaced a second list under the table that repeated
   every description with its own Edit and Delete button (22 Aug 2026) — a
   duplicate of the table on a wide screen. Buttons at the END of a row were
   the other option and are unreachable at 440px, where the table scrolls
   sideways. Save/Cancel/Delete are plain <button>s: the site-wide rule
   already gives them the 44x44 minimum. */
tr.entry-row { cursor: pointer; }
tr.entry-row:hover { background: var(--hover); }

/* The panel row exists in the markup for every entry, so it has to be gone
   rather than merely empty when closed — an empty <tr> still draws its
   borders and padding. Note [hidden] above uses !important for the panel
   div itself; this is the row around it. */
tr.entry-control { display: none; }
tr.entry-control.editing { display: table-row; }
td.edit-cell { padding: 0 0 10px; border-top: 0; }

.edit-panel {
    margin-top: 0;
    padding: 12px;
    /* --bg, not a literal: this is a box nested inside a card, the same
       situation .daycard is in and the same answer. It was #141414 until
       30 Aug 2026 — a neutral grey on a navy page, the last survivor of the
       set the 25 Aug audit replaced, and the largest surface among them.
       Not --recess, which is what the inputs inside it use: a panel and its
       own fields at the same value is the 1.00-contrast defect that audit
       found on the buttons. */
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.edit-panel[hidden] { display: none; }
.edit-panel .ef-wide { grid-column: 1 / -1; }
.edit-panel label { margin-bottom: 4px; }
.edit-panel-actions { display: flex; flex-direction: column; gap: 8px; }
.edit-panel-actions button { width: 100%; }

.big { font-size: 20px; }

/* A fold for setup text that is read once, e.g. the "how this is measured" notes. */
details > summary { cursor: pointer; color: var(--dim); margin: 8px 0; }
details[open] > summary { margin-bottom: 12px; }
