  /* ── Contours tokens ─────────────────────────────────────── */
  :root {
    --screen:  #F3E8D7;
    --card:    #FBF5EA;
    --ink:     #234036;
    --muted:   #7D8660;
    --faint:   #A7B5A6;
    --accent:  #E6884B;
    --thread:  #7D8660;
    --hairline: rgba(35, 64, 54, 0.14);
    --thread-soft: rgba(125, 134, 96, 0.16);
    --shadow: 0 2px 14px rgba(35, 64, 54, 0.07);
    --ok: #5B9057;
    --warn: #D9A63C;
    --due: #C9584F;
    --serif: "Iowan Old Style", "Palatino Nova", Palatino, "Book Antiqua", Georgia, serif;
    --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --screen:  #14211C;
      --card:    #1F3229;
      --ink:     #F0E9DC;
      --muted:   #A7B5A6;
      --faint:   #6C7A6B;
      --accent:  #ED9B63;
      --thread:  #A7B5A6;
      --hairline: rgba(240, 233, 220, 0.14);
      --thread-soft: rgba(167, 181, 166, 0.18);
      --shadow: 0 2px 14px rgba(0, 0, 0, 0.35);
    }
  }

  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  body {
    background: var(--screen);
    color: var(--ink);
    font-family: var(--sans);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
  }
  a { color: var(--accent); }
  h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.15; margin: 0; }
  button { font-family: var(--sans); cursor: pointer; }
  button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
  }

  .eyebrow {
    font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.13em;
    text-transform: uppercase; color: var(--muted);
  }

  /* ── Chrome ──────────────────────────────────────────────── */
  header.topbar {
    position: sticky; top: 0; z-index: 10;
    display: flex; align-items: center; gap: 1rem;
    padding: 0.7rem 1.2rem;
    background: color-mix(in srgb, var(--screen) 88%, transparent);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--hairline);
  }
  .brand { font-family: var(--serif); font-size: 1.25rem; text-decoration: none; color: var(--ink); }
  .brand .dot { color: var(--accent); }
  .topbar .spacer { flex: 1; }

  /* ── Freshness ───────────────────────────────────────────────
     ★ Badge the shortfall, never the success. There is no "up to date" state
     with a tick: the quiet form states a time, and the loud form only appears
     when a refresh has FAILED and the data is older than STALE_AFTER_MS.
     Both are buttons — a statement of staleness you cannot act on is half the
     defect it reports. */
  /* View rows: a presentation, not a form. Selectable and copyable by default. */
  .view-rows { display: grid; grid-template-columns: auto minmax(0, 1fr);
    gap: 0.35rem 0.9rem; margin: 0.2rem 0 0.4rem; }
  .view-rows dt { color: var(--faint); font-size: 0.78rem; text-transform: uppercase;
    letter-spacing: 0.05em; padding-top: 0.15rem; }
  .view-rows dd { margin: 0; overflow-wrap: anywhere; }
  .view-rows dd.mono { font-family: var(--mono, ui-monospace, monospace);
    user-select: all; }   /* one click selects the whole reference */
  .muted-note { color: var(--muted); font-size: 0.88rem; margin: 0 0 0.6rem; }

  .freshness {
    font: inherit; font-size: 0.78rem; color: var(--faint);
    background: none; border: 0; padding: 0.25rem 0.4rem; border-radius: 6px;
    cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
    white-space: nowrap;
  }
  .freshness:hover { color: var(--muted); background: var(--thread-soft); }
  /* Keyboard parity: this is a real control, so it shows focus like one.
     Not hover-only — see the .row-actions note below. */
  .freshness:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
  .fresh-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent); flex: none;
  }
  /* Asked for and failed: a sentence, because somebody is waiting for it. */
  .freshness.is-asked-failed {
    color: #8A4B00; background: #FFF1DF; border: 1px solid #F0C489;
    font-size: 0.78rem; font-weight: 600; white-space: normal;
  }
  @media (prefers-color-scheme: dark) {
    .freshness.is-asked-failed { color: #FFD9A8; background: #3A2A12; border-color: #6B4A1C; }
  }
  .freshness.is-stale {
    color: #8A4B00; background: #FFF1DF; border: 1px solid #F0C489;
    font-size: 0.8rem; font-weight: 600; white-space: normal;
  }
  @media (prefers-color-scheme: dark) {
    .freshness.is-stale { color: #FFD9A8; background: #3A2A12; border-color: #6B4A1C; }
  }
  /* The TIME is a desktop nicety; the WARNING is not — so below the phone
     breakpoint the reassurance goes and the shortfall stays. Same rule the
     element already follows (badge the shortfall), applied to width.
     ⚠️ **UNVERIFIED at this width.** The app's own frame-ancestors header
     blocks iframe probing and `resize_window` did not move the viewport, so
     nothing has SEEN this rule apply. The 4px overflow that prompted it was
     measured by constraining an element's width, which does not re-evaluate a
     media query — an invalid method, and the reading is withdrawn. The rule is
     kept because it is right by the stated design rule, not because it was
     observed. Ten seconds on a phone settles it. */
  @media (max-width: 640px) {
    .freshness:not(.is-stale) { display: none; }
    .freshness.is-stale { font-size: 0.72rem; padding: 0.2rem 0.35rem; }
  }
  .topbar .who { font-size: 0.8rem; color: var(--faint); }

  main { max-width: 56rem; margin: 0 auto; padding: 1.4rem 1.2rem 5rem; }

  /* ── Pane system ─────────────────────────────────────────────
     ★ What each breakpoint BUYS. Today there is no desktop layout to improve,
     only "not a phone", so these are stated as purchases rather than sizes.

       < 640px   phone. One column. Unchanged — this is the existing
                 breakpoint and nothing here touches it.
       640–1023  one column, up to 56rem. Buys NOTHING new, deliberately: a
                 laptop at 1024 is the first width where a second pane fits
                 without squeezing either side, and a pane that appears at 800
                 would be two cramped columns instead of one good one.
       >= 1024   TWO PANES. Buys master/detail: the list stays put while you
                 move through it, which is what kills the page-and-back round
                 trip that makes 29 bookings tedious.
       >= 1600   buys the list more room (22rem), not the detail. The detail
                 measure is FIXED at 46rem.

     ⚠️ The detail pane is capped at 46rem = 736px, which is NARROWER than
     today's 896px single column. That is the whole point: width buys a second
     pane, never a longer line. Total in pane mode ~1120px — 58% of a 1920
     window against today's 47%, with every line shorter than it is now. */
  /* < 1024: exactly as it always did. ⚠️ The list pane is HIDDEN rather than
     stacked — seen in Chrome at 980px, where it rendered above the hero as a
     second copy of navigation the day cards below already provide. A pane with
     no room to be a pane is not content; it is duplication. */
  main.panes { max-width: 56rem; }
  main.panes > .pane-list { display: none; }
  .pane-list > .pane-title { font-size: 0.72rem; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--faint); margin: 0 0 0.5rem; }

  @media (min-width: 1024px) {
    main.panes {
      max-width: 70rem;
      display: grid;
      grid-template-columns: 18rem minmax(0, 46rem);
      gap: 1.6rem;
      align-items: start;
    }
    /* The list holds its own scroll so a long day index cannot push the
       detail pane down the page. */
    .pane-list {
      position: sticky; top: 4.2rem;
      max-height: calc(100vh - 6rem); overflow-y: auto;
    }
    .pane-detail { min-width: 0; }              /* or long words blow the grid out */
    main.panes > .pane-list { display: block; }
  }
  @media (min-width: 1600px) {
    main.panes { max-width: 74rem; grid-template-columns: 22rem minmax(0, 46rem); }
  }

  /* The day index in the list pane. */
  .pane-nav { display: flex; flex-direction: column; gap: 0.1rem; }
  .pane-nav a {
    display: flex; justify-content: space-between; gap: 0.6rem;
    padding: 0.4rem 0.55rem; border-radius: 7px;
    color: var(--ink); text-decoration: none; font-size: 0.86rem;
  }
  .pane-nav a:hover { background: var(--thread-soft); }
  .pane-nav a.sel { background: var(--thread-soft); font-weight: 600; }
  .pane-nav a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
  .pane-nav .n { color: var(--faint); font-size: 0.78rem; flex: none; }

  /* ── Buttons ─────────────────────────────────────────────── */
  .btn {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.5rem 1.05rem; border-radius: 999px; border: none;
    font-weight: 600; font-size: 0.9rem; text-decoration: none;
  }
  .btn-primary { background: var(--accent); color: #FFF8F0; }
  .btn-ghost { background: var(--card); color: var(--ink); border: 1.5px solid var(--hairline); }
  .btn-danger { background: transparent; color: var(--due); border: 1.5px solid var(--due); }
  .btn-bare { background: none; border: none; color: var(--accent); font-weight: 600; padding: 0.3rem 0.5rem; font-size: 0.85rem; }
  .btn[disabled] { opacity: 0.5; cursor: default; }

  /* ── Cards & lists ───────────────────────────────────────── */
  .card {
    background: var(--card); border: 1px solid var(--hairline);
    border-radius: 16px; box-shadow: var(--shadow); padding: 1rem 1.15rem;
  }
  .trip-card { display: block; text-decoration: none; color: var(--ink); margin-bottom: 0.8rem; transition: transform 0.12s ease; }
  .trip-card:hover { transform: translateY(-1px); }
  .trip-card h3 { font-size: 1.25rem; margin-bottom: 0.15rem; }
  .trip-card .sub { color: var(--muted); font-size: 0.9rem; }
  .trip-card .cover { display: block; width: 100%; height: 150px; object-fit: cover;
    border-radius: 10px; margin-bottom: 0.65rem; background: var(--hairline); }
  .trip-hero { display: block; width: 100%; height: 190px; object-fit: cover;
    border-radius: 16px; margin-bottom: 0.9rem; background: var(--hairline); }
  .section-label { margin: 1.6rem 0 0.7rem; }

  /* ★ **Visible, always.** These were `opacity: 0` until hover, with a
     `@media (hover: none)` rule turning them back on for touch — i.e. the TOUCH
     experience was the correct one and the POINTER experience was the degraded
     one, which is the wrong way round. Step 2 raised the cost: the list pane is
     now a permanent fixture, so these are actions in the primary navigation
     surface, invisible until hovered, in front of the users newest to the
     product — the phone-plus-Windows-laptop audience for whom this is the only
     desktop client.
     The app learned this three times (the Place field's hidden swipe, the
     booking map's hidden tap, the Directions pill) and the answer was the same
     each time: a visible affordance beats a hidden gesture. They recede by
     EMPHASIS — muted until the row is hovered or focused — never by absence. */
  .row-actions { display: flex; gap: 0.3rem; opacity: 0.72; transition: opacity 0.12s; }
  .item-row:hover .row-actions, .booking-row:hover .row-actions,
  .item-row:focus-within .row-actions, .booking-row:focus-within .row-actions { opacity: 1; }

  /* ── Trip page ───────────────────────────────────────────── */
  .trip-head { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
  .trip-head h1 { font-size: clamp(1.7rem, 5vw, 2.4rem); flex: 1 1 14rem; }
  .trip-head .meta { color: var(--muted); font-size: 0.92rem; }

  .day-card { padding: 0; overflow: hidden; margin-bottom: 0.7rem; }
  .day-head {
    display: flex; align-items: center; gap: 0.8rem;
    padding: 0.8rem 1.1rem; cursor: pointer; user-select: none;
  }
  .day-head:hover { background: var(--thread-soft); }
  .day-head .when b { font-size: 1rem; }
  .day-head .when .day-num { font-family: var(--mono); font-size: 0.7rem; color: var(--faint); margin-left: 0.5rem; }
  .day-head .day-title { color: var(--muted); font-size: 0.88rem; }
  .day-sum { margin-left: auto; display: flex; align-items: center; gap: 0.55rem; color: var(--muted); font-size: 0.8rem; white-space: nowrap; }
  .chev { color: var(--faint); transition: transform 0.15s; font-size: 0.8rem; }
  .day-card.open .chev { transform: rotate(180deg); }
  .day-card.open .day-head { border-bottom: 1px solid var(--hairline); }
  .day-body { padding: 0.5rem 1.1rem 1rem; }
  .mini-dots { display: inline-flex; gap: 0.2rem; align-items: center; }
  .mini-dots .status-dot { width: 0.5rem; height: 0.5rem; }

  .day-panel { border-left: 2px solid var(--thread-soft); margin-left: 0.4rem; padding-left: 1.3rem; position: relative; }
  .day-panel .daymeta { color: var(--muted); font-size: 0.88rem; margin-bottom: 0.9rem; }

  .seg { display: inline-flex; border: 1.5px solid var(--hairline); border-radius: 999px; overflow: hidden; }
  .seg button { border: none; background: var(--card); color: var(--muted); padding: 0.42rem 1rem; font-size: 0.85rem; font-weight: 600; }
  .seg button.sel { background: var(--accent); color: #FFF8F0; }

  .item-row {
    display: flex; gap: 0.75rem; align-items: baseline; position: relative;
    padding: 0.55rem 0.6rem; border-radius: 12px; margin-left: -0.6rem;
  }
  .item-row:hover { background: var(--thread-soft); }
  .item-row::before {
    content: ""; position: absolute; left: -1.68rem; top: 1.05rem;
    width: 0.55rem; height: 0.55rem; border-radius: 50%;
    background: var(--thread); opacity: 0.65;
  }
  .item-time { font-family: var(--mono); font-size: 0.78rem; color: var(--muted); min-width: 3.1rem; }
  .item-main { flex: 1; min-width: 0; }
  .item-title { font-weight: 600; font-size: 0.95rem; }
  .item-title .kind { margin-right: 0.35rem; }
  .item-body { color: var(--muted); font-size: 0.85rem; white-space: pre-wrap; overflow-wrap: anywhere; }
  .badge {
    display: inline-block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em;
    padding: 0.1rem 0.45rem; border-radius: 999px; border: 1px solid var(--hairline);
    color: var(--muted); vertical-align: 0.1rem; margin-left: 0.35rem;
  }
  .badge.tentative { color: var(--warn); border-color: var(--warn); }

  /* ── Bookings ────────────────────────────────────────────── */
  .booking-row { display: flex; gap: 0.7rem; align-items: baseline; padding: 0.5rem 0.6rem; border-radius: 12px; margin-left: -0.6rem; }
  .booking-row:hover { background: var(--thread-soft); }
  .booking-card { padding: 0; overflow: hidden; margin-bottom: 0.6rem; }
  .booking-card .booking-row { margin: 0; border-radius: 0; padding: 0.7rem 1.1rem; }
  .booking-card.open .booking-row { border-bottom: 1px solid var(--hairline); }
  .booking-card.open .chev { transform: rotate(180deg); }
  .booking-detail {
    display: grid; grid-template-columns: auto 1fr; gap: 0.3rem 1.2rem;
    padding: 0.9rem 1.1rem; font-size: 0.88rem;
  }
  .booking-detail .bk-label { color: var(--muted); font-size: 0.78rem; font-weight: 600; align-self: baseline; }
  .status-dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; flex: 0 0 auto; align-self: center; }
  .status-dot.ok { background: var(--ok); }
  .status-dot.warn { background: var(--warn); }
  .status-dot.due { background: var(--due); }
  .status-dot.off { background: var(--faint); }
  .booking-main { flex: 1; min-width: 0; }
  .booking-title { font-weight: 600; font-size: 0.93rem; }
  .booking-sub { color: var(--muted); font-size: 0.82rem; }

  /* ── Forms / modal ───────────────────────────────────────── */
  .overlay {
    position: fixed; inset: 0; z-index: 50; display: flex;
    align-items: flex-start; justify-content: center;
    background: rgba(20, 33, 28, 0.45); padding: 4vh 1rem;
    overflow-y: auto;
  }
  .modal { width: 100%; max-width: 30rem; padding: 1.3rem 1.4rem 1.5rem; }
  .modal h2 { font-size: 1.35rem; margin-bottom: 1rem; }
  .field { margin-bottom: 0.85rem; }
  .field label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--muted); margin-bottom: 0.25rem; }
  .field input, .field select, .field textarea {
    width: 100%; padding: 0.5rem 0.65rem; border-radius: 10px;
    border: 1.5px solid var(--hairline); background: var(--screen);
    color: var(--ink); font-family: var(--sans); font-size: 0.92rem;
  }
  .field textarea { min-height: 4.2rem; resize: vertical; }
  .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
  .modal-actions { display: flex; gap: 0.6rem; justify-content: flex-end; margin-top: 1.1rem; flex-wrap: wrap; }
  .modal-actions .left { margin-right: auto; }
  .form-error { color: var(--due); font-size: 0.85rem; margin-top: 0.6rem; }

  /* ── Login / landing (PRD §22: the workflow, told beautifully) ── */
  .login-wrap { display: flex; align-items: center; justify-content: center; padding: 1rem; }
  .login { max-width: 22rem; width: 100%; text-align: center; padding: 2rem 1.6rem; }
  .login h1 { font-size: 2.1rem; margin-bottom: 0.3rem; }
  .login p { color: var(--muted); font-size: 0.9rem; }

  .landing-hero {
    position: relative; min-height: 58vh; overflow: hidden;
    display: flex; align-items: center; justify-content: center; text-align: center;
  }
  .landing-hero canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
  .landing-hero .inner { position: relative; padding: 3.2rem 1.5rem; max-width: 44rem; }
  .landing-wordmark {
    font-family: var(--serif); font-weight: 500; line-height: 1.05;
    font-size: clamp(2.8rem, 8vw, 4.6rem); text-wrap: balance; margin: 0.8rem 0 0;
  }
  .landing-tagline {
    font-family: var(--serif); font-size: clamp(1.1rem, 3vw, 1.4rem);
    color: var(--muted); max-width: 34ch; margin: 1rem auto 1.8rem; text-wrap: balance;
  }
/* The how-to link sits under the hero CTA: secondary to "create account", but
   deliberately above the fold — getting started with nothing is the pitch. */
.landing-howto { margin-top: 0.9rem; font-size: 0.95rem; }
.landing-howto a { color: var(--accent); font-weight: 600; text-decoration: none; }
.landing-howto a:hover { text-decoration: underline; }
  .landing-section {
    max-width: 58rem; margin: 0 auto; padding: 2.6rem 1.5rem 0;
    display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: center;
  }
  .landing-section.flip .vignette { order: 2; }
  @media (max-width: 640px) {
    .landing-section { grid-template-columns: 1fr; gap: 1rem; }
    .landing-section.flip .vignette { order: 0; }
  }
  .landing-section h2 {
    font-family: var(--serif); font-weight: 500;
    font-size: clamp(1.5rem, 4vw, 2rem); line-height: 1.15; margin: 0.3rem 0 0.7rem;
    text-wrap: balance;
  }
  .landing-section p { color: var(--muted); margin: 0; max-width: 48ch; }
  .landing-section p strong { color: var(--ink); }
  .vignette {
    background: var(--card); border: 1px solid var(--hairline); border-radius: 20px;
    box-shadow: var(--shadow); padding: 1.2rem;
    display: flex; align-items: center; justify-content: center;
  }
  .vignette svg { width: 100%; height: auto; max-width: 340px; display: block; }
  .read-more {
    background: none; border: none; padding: 0; margin-top: 0.7rem;
    color: var(--accent); font: inherit; font-size: 0.92rem; font-weight: 600;
    cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem;
  }
  .read-more::after { content: "▾"; font-size: 0.8em; transition: transform 0.2s; }
  .read-more[aria-expanded="true"]::after { transform: rotate(180deg); }
  .read-more-body { display: none; margin-top: 0.7rem; }
  .read-more-body.open { display: block; }
  .read-more-body p { margin: 0 0 0.6rem; font-size: 0.95rem; }
  .landing-cta { text-align: center; padding: 3rem 1.5rem 0.5rem; }
  /* ★ Directly above the sign-in card. The moment someone is deciding whether
     to commit is exactly when "but how does this actually work?" is the
     question, so this is bold and larger than the eyebrow above it. */
  .landing-howto-strong { margin: 0.9rem 0 0; font-size: 1.05rem; font-weight: 700; }
  .landing-howto-strong a { color: var(--accent); text-decoration: none;
    border-bottom: 2px solid var(--accent); padding-bottom: 1px; }
  .landing-howto-strong a:hover { opacity: 0.8; }
  .landing-footer { text-align: center; color: var(--muted); font-size: 0.85rem; padding: 1.6rem 0 3rem; }
  /* §28 homepage language toggle — a small flag pair, top corner. */
  .lang-toggle {
    position: absolute; top: 0.9rem; right: 0.9rem; z-index: 5;
    display: inline-flex; gap: 0.15rem; padding: 0.15rem;
    background: var(--card); border: 1px solid var(--hairline); border-radius: 999px;
    box-shadow: var(--shadow);
  }
  .lang-toggle button {
    border: none; background: none; cursor: pointer; border-radius: 999px;
    padding: 0.15rem 0.4rem; font-size: 1.05rem; line-height: 1; opacity: 0.45;
    transition: opacity 0.15s, background 0.15s;
  }
  .lang-toggle button:hover { opacity: 0.8; }
  .lang-toggle button.sel { opacity: 1; background: var(--screen); }

  /* ── Toast ───────────────────────────────────────────────── */
  #toast {
    position: fixed; bottom: 1.2rem; left: 50%; transform: translateX(-50%);
    background: var(--ink); color: var(--screen);
    padding: 0.55rem 1.1rem; border-radius: 999px; font-size: 0.85rem;
    opacity: 0; transition: opacity 0.25s; pointer-events: none; z-index: 99;
    max-width: 90vw;
  }
  #toast.show { opacity: 1; }

  .empty { color: var(--faint); font-size: 0.9rem; padding: 0.6rem 0; }

  .avatar {
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; overflow: hidden; background: var(--thread-soft);
    color: var(--thread); border: 1.5px solid var(--hairline); flex: 0 0 auto;
  }

  .trip-tabs { display: flex; gap: 0.4rem; margin: 0.2rem 0 1rem; flex-wrap: wrap; }
  .trip-tabs a {
    text-decoration: none; font-weight: 600; font-size: 0.88rem;
    padding: 0.35rem 0.95rem; border-radius: 999px;
    color: var(--muted); background: var(--card); border: 1px solid var(--hairline);
  }
  .trip-tabs a.sel { background: var(--accent); border-color: var(--accent); color: #FFF8F0; }

  #map { height: 320px; border-radius: 16px; border: 1px solid var(--hairline); margin-bottom: 1rem; }

  .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0.8rem; margin-bottom: 1.4rem; }
  .stat { text-align: left; }
  .stat b { display: block; font-size: 1.6rem; font-family: var(--serif); font-weight: 500; }
  .stat span { color: var(--muted); font-size: 0.8rem; }
  .bars { display: flex; align-items: flex-end; gap: 3px; height: 60px; margin-top: 0.5rem; }
  .bars i { flex: 1; background: var(--thread); opacity: 0.55; border-radius: 2px 2px 0 0; min-height: 2px; }
  .admin-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
  .admin-table th { text-align: left; color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; padding: 0.4rem 0.6rem; }
  .admin-table td { padding: 0.5rem 0.6rem; border-top: 1px solid var(--hairline); }
  .admin-table select { border-radius: 8px; border: 1.5px solid var(--hairline); background: var(--screen); color: var(--ink); padding: 0.2rem 0.4rem; }

  .photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); gap: 0.5rem; margin: 0.6rem 0; }
  .photo-grid img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; border: 1px solid var(--hairline); cursor: zoom-in; }
  /* §39.10: a photo the server no longer stores is a grey privacy card, not a
     broken image — an absence stated as architecture, linking to the policy. */
  .photo-greybox { display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.3rem; aspect-ratio: 1; border-radius: 10px; border: 1px dashed var(--hairline);
    background: rgba(128,128,128,0.10); color: var(--muted); text-decoration: none;
    text-align: center; padding: 0.45rem; }
  .photo-greybox:hover { color: var(--ink); background: rgba(128,128,128,0.16); }
  .photo-greybox .pg-mark { font-size: 1.4rem; line-height: 1; opacity: 0.85; }
  .photo-greybox .pg-note { font-size: 0.6rem; line-height: 1.25; }

  /* Lightbox: photos step across stops with ← → (Bo, v4.18). */
  #lightbox {
    position: fixed; inset: 0; z-index: 90; background: rgba(10, 14, 12, 0.92);
    display: flex; align-items: center; justify-content: center;
  }
  #lightbox img { max-width: 92vw; max-height: 82vh; object-fit: contain; border-radius: 6px; }
  #lightbox .lb-caption {
    position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%);
    color: #F0E9DC; font-size: 0.9rem; text-align: center; max-width: 80vw;
  }
  #lightbox .lb-caption b { display: block; font-size: 1rem; }
  #lightbox button {
    position: absolute; background: rgba(240, 233, 220, 0.12); border: none;
    color: #F0E9DC; font-size: 1.5rem; border-radius: 50%;
    width: 2.8rem; height: 2.8rem; cursor: pointer;
  }
  #lightbox button:hover { background: rgba(240, 233, 220, 0.25); }
  #lightbox .lb-prev { left: 1rem; top: 50%; transform: translateY(-50%); }
  #lightbox .lb-next { right: 1rem; top: 50%; transform: translateY(-50%); }
  #lightbox .lb-close { top: 1rem; right: 1rem; font-size: 1.1rem; }
