/* FOUNDERS Talk Africa - board design system (v2 "soft + depth", LOCKED).
 * Moved verbatim out of home.html so the board and the account pages share
 * one source of truth. Restyling here changes the live board - treat the
 * v2 lock as the authority.
 */

  :root {
    --bg: #F7F6F3;
    --glow: #FBEFD9;
    --surface: #FFFFFF;
    --ink: #16140F;
    --muted: #6B6660;
    --hair: #ECEAE4;
    --accent: #C8841E;
    --accent-soft: #F6E9D2;
    --good: #2E7D5B;
    --ask: #2D6CDF;
    --tell: #2E7D5B;
    --show: #C8841E;
    --find: #7C5CD6;
    /* Shadows: shadow-as-border (3 layers) — see better-ui/surfaces */
    /* soft, warm, diffuse — locked v2 */
    --shadow: 0 2px 5px rgba(20,18,12,.04), 0 22px 46px -20px rgba(200,132,30,.20);
    --shadow-hover: 0 4px 8px rgba(20,18,12,.05), 0 34px 64px -22px rgba(200,132,30,.28);
    --shadow-border: var(--shadow);
    --shadow-border-hover: var(--shadow-hover);
    /* Spacing scale — 4px base, single rhythmic ladder */
    --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
    --s5: 20px; --s6: 24px; --s7: 32px; --s8: 48px;
    --radius: 22px;
    --r-sm: 13px;
    --maxw: 1200px;
    --chrome-h: 67px;   /* the band's MEASURED height (40px island + 2x13 padding +
                           1px border). The band enforces it via min-height and
                           both rails pin to it -- one source of truth. */
    --gap: 18px;
  }
  [data-theme="dark"] {
    --bg: #16140F;
    --glow: #2C2310;
    --surface: #1F1C16;
    --ink: #F7F6F3;
    --muted: #9C948A;
    --hair: #322E27;
    --accent: #E2A23C;
    --accent-soft: #2C2415;
    --good: #4FB083;
    --ask: #6BA1F0;
    --tell: #4FB083;
    --show: #E2A23C;
    --find: #A98FE6;
    --shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 24px 50px -22px rgba(0,0,0,.6);
    --shadow-hover: inset 0 1px 0 rgba(255,255,255,.08), 0 34px 70px -22px rgba(0,0,0,.7);
    --shadow-border: var(--shadow);
    --shadow-border-hover: var(--shadow-hover);
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  [hidden] { display: none !important; }
  body {
    font-family: 'Inter', system-ui, sans-serif;
    color: var(--ink);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    background:
      radial-gradient(38% 30% at 88% 12%, rgba(200,132,30,.16) 0%, transparent 60%),
      radial-gradient(34% 28% at 12% 42%, rgba(124,92,214,.10) 0%, transparent 62%),
      radial-gradient(30% 26% at 78% 78%, rgba(79,176,131,.09) 0%, transparent 60%),
      radial-gradient(95% 65% at 100% 0%, var(--glow) 0%, transparent 55%),
      var(--bg);
    background-attachment: fixed;
  }
  h1,h2,h3,.display { font-family: 'Satoshi', 'Inter', sans-serif; }
  .mono { font-family: 'JetBrains Mono', monospace; font-variant-numeric: tabular-nums; }

  /* Icons — Phosphor sprite (inlined via board/_icons.html) */
  .ic { width: 1em; height: 1em; display: block; flex: none; fill: currentColor; }
  .ic-12 { font-size: 12px; } .ic-14 { font-size: 14px; } .ic-16 { font-size: 16px; }
  .ic-18 { font-size: 18px; } .ic-20 { font-size: 20px; } .ic-22 { font-size: 22px; }
  /* inline icon+label pair: 6px is an optical gap, not a rhythmic one */
  .mi { display: inline-flex; align-items: center; gap: 6px; }
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
  }

  /* Top bar */
  /* Chrome band: brand · island · account, one row. The island is the only
     desktop navigation, so this band is the single piece of chrome above the
     feed. It is sticky at top:0, so its height IS --chrome-h -- it enforces
     that with min-height rather than relying on the contents adding up. */
  .topbar {
    position: sticky; top: 0; z-index: 40;
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--s4);
    min-height: var(--chrome-h);
    padding: calc(var(--s3) + env(safe-area-inset-top, 0px)) var(--s7);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--hair);
  }
  /* Pinned to the last column so an empty centre column cannot pull the
     account controls into the middle (the sign-in pages have no island). */
  .band-end { grid-column: 3; justify-self: end; display:flex; align-items:center; gap: var(--s2); }
  .brand { display: flex; flex-direction: column; line-height: 1.1; }
  .brand .name { font-family:'Satoshi'; font-weight:700; font-size:18px; letter-spacing:-.01em; }
  .spacer { flex: 1; }
  .search {
    display:flex; align-items:center; gap:var(--s2);
    background: color-mix(in srgb, var(--bg) 70%, var(--surface)); border:1px solid var(--hair);
    border-radius: 999px; padding: 9px 16px; width: 270px;
    box-shadow: inset 0 1px 2px rgba(0,0,0,.03);
  }
  .search input { border:0; background:transparent; outline:0; color:var(--ink); font-size:14px; width:100%; }
  .search svg { opacity:.5; }
  .btn {
    border:1px solid var(--hair); background:var(--surface); color:var(--ink);
    border-radius:999px; padding: 9px 18px; font-size:14px; font-weight:500; cursor:pointer;
    text-decoration:none; display:inline-flex; align-items:center; gap:6px;
    box-shadow: 0 1px 2px rgba(0,0,0,.03);
  }
  .btn.primary { background: var(--ink); color: var(--bg); border-color: var(--ink); }
  .btn.icon { padding: var(--s2); display:grid; place-items:center; }
  .theme-toggle { cursor:pointer; }
  .theme-toggle .i-sun { display: none; }
  [data-theme="dark"] .theme-toggle .i-moon { display: none; }
  [data-theme="dark"] .theme-toggle .i-sun { display: block; }

  /* THE ISLAND. One row, centred in the band. Adapted from the reference dock
     (dark pill, 4px pad, 40px tall, 2px gap, 999px radius) but rebuilt on board
     tokens: the dark is --ink and the inverted active pill is --bg, so the
     island self-inverts in dark mode instead of staying a foreign black.

     Deliberately no fixed item widths -- add an item and the dock re-centres
     itself, instead of overflowing a hand-tuned total. */
  .dock {
    display:inline-flex; align-items:center; gap:2px;
    background: var(--ink); padding: 4px; border-radius:999px; height:40px;
    box-shadow: 0 8px 20px rgba(20,18,12,.10);
  }
  [data-theme="dark"] .dock { box-shadow: 0 8px 20px rgba(0,0,0,.45); }
  .dock-item {
    display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 14px;
    border:0; background:none; cursor:pointer; border-radius:999px; white-space:nowrap;
    color: color-mix(in srgb, var(--bg) 64%, transparent);
    font-family:inherit; font-size:13.5px; font-weight:500;
  }
  .dock-item:hover { color: color-mix(in srgb, var(--bg) 92%, transparent); }
  .dock-item.active { background: var(--bg); color: var(--ink); }
  .dock-item.active:hover { color: var(--ink); }
  /* Extension point: the board search as a dock item. Styled now, so adding it
     later is markup only. It still needs a view and a URL first -- the old
     input had no form, action or name, so it searched nothing. See _topbar.html. */
  .dock .search {
    width:auto; min-width:140px; height:32px; padding:0 12px;
    background: color-mix(in srgb, var(--bg) 14%, transparent);
    border:0; box-shadow:none;
  }
  .dock .search input { color: color-mix(in srgb, var(--bg) 94%, transparent); font-size:13px; }
  .dock .search input::placeholder { color: color-mix(in srgb, var(--bg) 52%, transparent); }

  /* Layout */
  .shell {
    max-width: var(--maxw); margin: 0 auto; padding: 28px 26px;
    display: grid; grid-template-columns: 224px 1fr 304px; gap: 26px;
    align-items: start;
  }
  .rail { position: sticky; top: var(--chrome-h); display:flex; flex-direction:column; gap:10px; }
  /* The section nav that used to be styled here is the island in the band now
     (.dock / .dock-item), so these rules were removed along with the rail buttons. */
  .profile {
    margin-top: var(--s6); padding: var(--s4); border:1px solid var(--hair); border-radius:var(--r-sm);
    background:var(--surface); font-size:13px;
  }
  .profile b { font-size:14px; }
  .profile .inv { color:var(--accent); font-weight:600; margin-top:var(--s2); }

  .feed { display:flex; flex-direction:column; gap: 20px; min-width:0; }
  /* Cards are children of the list containers, NOT of .feed - the inter-card
     gap must live here or the cards stack flush against each other. */
  #city-list, #world-list { display:flex; flex-direction:column; gap: 22px; }
  .feed-head { display:flex; align-items:center; justify-content:space-between; margin-bottom: 0; padding: 0 2px; }
  .feed-head h2 { font-size:24px; letter-spacing:-.025em; }
  .feed-head .sort { font-size:13px; color:var(--muted); }

  /* Shelf filter */
  .shelf-row { display:flex; gap:var(--s2); flex-wrap:wrap; }
  .shelf-chip {
    font-size:12px; font-weight:600; padding: var(--s2) var(--s4); border-radius:999px;
    border:1px solid var(--hair); background:var(--bg); color:var(--muted); cursor:pointer;
    text-decoration:none;
  }
  .shelf-chip.active { background:var(--ink); color:var(--bg); border-color:var(--ink); }

  /* Card — frosted glass shell */
  .card {
    position: relative;
    background: rgba(255,255,255,.48);
    backdrop-filter: blur(25px) saturate(150%);
    -webkit-backdrop-filter: blur(25px) saturate(150%);
    border: 1px solid rgba(255,255,255,.75);
    border-radius: 28px;
    box-shadow:
      0 0 0 1px rgba(20,18,12,.05),
      inset 0 1px 0 rgba(255,255,255,.9),
      0 20px 46px -16px rgba(20,18,12,.18);
    padding: 26px 28px 24px;
    transition: transform .25s cubic-bezier(.165,.84,.44,1), box-shadow .25s ease;
    animation: fadeInScaleUp .7s cubic-bezier(.165,.84,.44,1) both;
    overflow: hidden;
  }
  [data-theme="dark"] .card {
    background: rgba(34,30,23,.5);
    border-color: rgba(255,255,255,.14);
    box-shadow:
      0 0 0 1px rgba(0,0,0,.45),
      inset 0 1px 0 rgba(255,255,255,.07),
      0 20px 55px rgba(0,0,0,.55);
  }
  /* freshness marker — 11px amber square, top-right */
  .card::after {
    content:""; position:absolute; top:18px; right:18px; width:11px; height:11px; border-radius:3px;
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 78%, white), var(--accent));
    box-shadow: 0 2px 10px color-mix(in srgb, var(--accent) 55%, transparent);
    animation: fresh 2.6s ease-in-out infinite;
  }
  .card.aged::after { background: var(--hair); box-shadow: none; animation: none; }
  @keyframes fresh {
    0%,100% { box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 45%, transparent); }
    50%     { box-shadow: 0 2px 16px color-mix(in srgb, var(--accent) 72%, transparent); }
  }
  .card:hover { transform: translateY(-4px); box-shadow: 0 0 0 1px rgba(20,18,12,.05), 0 28px 56px -18px rgba(20,18,12,.22); }
  .card:nth-child(2) { animation-delay: 60ms; }
  .card:nth-child(3) { animation-delay: 120ms; }
  .card:nth-child(4) { animation-delay: 180ms; }
  .card:nth-child(5) { animation-delay: 240ms; }
  .card:nth-child(6) { animation-delay: 300ms; }
  .card > :last-child { margin-bottom: 0; }
  @keyframes fadeInScaleUp {
    from { opacity: 0; transform: translateY(25px) scale(.95); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }
  @keyframes rise { from { opacity:0; transform: translateY(10px);} to {opacity:1; transform:none;} }
  .card-top { display:flex; align-items:center; gap:11px; margin-bottom:13px; font-size:12px; color:var(--muted); flex-wrap:wrap; }
  .chip {
    display:inline-flex; align-items:center; gap:6px; font-weight:600; font-size:12px;
    padding:var(--s1) var(--s3); border-radius:999px; background: var(--bg); color:var(--ink);
  }
  .chip .d { width:6px; height:6px; border-radius:50%; }
  .chip.ask .d { background: var(--ask); } .chip.tell .d { background: var(--tell); }
  .chip.show .d { background: var(--show); } .chip.find .d { background: var(--find); }
  .world-tag { display:inline-flex; align-items:center; gap:6px; font-weight:600; color:var(--accent); }
  .domain { display:inline-flex; align-items:center; gap:6px; }
  .favi { width:14px; height:14px; border-radius:4px; background:var(--hair); display:inline-grid; place-items:center; font-size:9px; font-weight:700; color:var(--muted);}
  .card h3 { font-size:18px; line-height:1.32; letter-spacing:-.012em; margin-bottom:7px; padding-right:34px; }
  .card h3 a { color: var(--ink); text-decoration:none; }
  .card h3 a:hover { color: var(--accent); }
  .card .note { font-size:14px; line-height:1.6; color: var(--muted); margin-bottom:18px; }
  .card-foot { display:flex; align-items:center; gap:18px; font-size:13px; color:var(--muted); flex-wrap:wrap; }
  .card-foot .pts { font-family:'JetBrains Mono'; font-weight:700; color:var(--ink); }
  .card-foot .work { color: var(--good); font-weight:600; display:inline-flex; gap:6px; align-items:center; }
  .card-foot .src { color:var(--accent); font-weight:600; }
  .shelf-muted { color: var(--muted); }

  /* Right rail */
  /* The rail may never be taller than the window. A sticky element taller than
     the viewport pins with its tail below the fold, and no amount of scrolling
     brings it back: measured on prod, a 634px rail in a 454px window put the
     last card permanently out of view. Capping it and letting the *list* absorb
     the squeeze keeps the event card (and RSVP) on screen and the list
     reachable inside its own scroll. */
  .side {
    position: sticky; top: var(--chrome-h);
    align-self: start;                       /* sticky in a grid needs this */
    max-height: calc(100vh - var(--chrome-h) - var(--s4));   /* fallback */
    max-height: calc(100dvh - var(--chrome-h) - var(--s4));  /* dvh counts mobile chrome */
    display:flex; flex-direction:column; gap:18px;
  }
  /* RSVP must never be the thing that gets squashed, so the event card holds
     its full height and the news list is what shrinks and scrolls. */
  .side > .panel.event { flex: 0 0 auto; }
  .side > .panel:last-child {
    overflow-y: auto; min-height: 0;
    overscroll-behavior: contain;            /* don't chain the scroll to the page */
    scrollbar-width: thin;
  }
  .panel {
    background: rgba(255,255,255,.48);
    backdrop-filter: blur(25px) saturate(150%);
    -webkit-backdrop-filter: blur(25px) saturate(150%);
    border: 1px solid rgba(255,255,255,.75);
    border-radius: 28px; padding: 20px;
    box-shadow:
      0 0 0 1px rgba(20,18,12,.05),
      inset 0 1px 0 rgba(255,255,255,.9),
      0 20px 46px -14px rgba(20,18,12,.16);
  }
  [data-theme="dark"] .panel {
    background: rgba(34,30,23,.5);
    border-color: rgba(255,255,255,.14);
    box-shadow: 0 0 0 1px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.07), 0 20px 55px rgba(0,0,0,.55);
  }
  .event {
    background:
      radial-gradient(120% 90% at 100% 0%, color-mix(in srgb, var(--accent) 22%, transparent) 0%, transparent 60%),
      linear-gradient(165deg, color-mix(in srgb, var(--accent-soft) 60%, transparent), color-mix(in srgb, var(--surface) 45%, transparent) 70%);
    border-color: color-mix(in srgb, var(--accent) 35%, rgba(255,255,255,.7));
  }
  .event .vol { font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--accent); font-weight:700; }
  .event h3 { font-size:20px; margin:var(--s2) 0 var(--s1); letter-spacing:-.02em; }
  .event .meta { font-size:13px; color:var(--muted); display:flex; flex-direction:column; gap:var(--s2); }
  /* The countdown is where the card's bulk sits, so it is sized to read as a
     glance strip rather than three big tiles: 91px of card height before,
     ~60px after. Structure is unchanged -- still three tiles, number over
     label, just tighter padding, smaller numerals and less margin. */
  .countdown { display:flex; gap:var(--s1); margin:var(--s2) 0; }
  .cd { background:var(--surface); border:1px solid var(--hair); border-radius:10px; padding:var(--s2) var(--s1); text-align:center; flex:1; }
  .cd b { font-family:'JetBrains Mono'; font-size:14px; display:block; line-height:1.15; }
  .cd span { font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; line-height:1.2; }
  .panel h4 { font-size:13px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin-bottom:var(--s3); }
  .hi { display:flex; align-items:center; gap:var(--s3); padding:var(--s2) 0; border-top:1px solid var(--hair); font-size:13px; }
  .hi:first-of-type { border-top:0; }
  .hi .dot { width:6px; height:6px; border-radius:50%; background:var(--accent); flex:none; }
  .hi .ic { color: var(--accent); }
  .hi a { color:var(--ink); text-decoration:none; }
  .hi a:hover { color: var(--accent); }

  /* Pager — Previous / Next at the foot of a feed. Plain links: the page number
     lives in the URL, so a view is shareable, the back button behaves, and it
     works on a slow phone with no JS. 44px targets, same rule as the island. */
  .pager {
    display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
    padding-top: var(--s4); border-top: 1px solid var(--hair);
  }
  .pager .pg {
    display:inline-flex; align-items:center; min-height:44px; padding:0 var(--s4);
    border:1px solid var(--hair); border-radius:999px;
    background:var(--surface); color:var(--ink);
    text-decoration:none; font-size:13px; font-weight:600;
    transition: border-color .18s ease, color .18s ease;
  }
  .pager a.pg:hover { color:var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--hair)); }
  .pager .pg.off { color:var(--muted); opacity:.5; }
  .pager .pg-count { font-family:'JetBrains Mono'; font-size:12px; color:var(--muted); }

  /* Short windows. Measured: event card 335px, news list 245px (1440x800);
     209px and 123px once compacted (999x454).  available = window - chrome - gutter.
       below 480px  the 335px card leaves too little of the window for the news
                    list to be worth showing, so the card compacts to 209px
                    (date, venue and RSVP survive; the eyebrow and the
                    countdown's bulk do not) and stays pinned and reachable.
       below 320px  not even the compact card fits, so pinning buys nothing and
                    costs reachability — the rail scrolls with the page instead. */
  @media (max-height: 480px) {
    .event .vol { display:none; }
    .event { padding: var(--s4); }
    .event h3 { font-size:17px; margin: 0 0 var(--s2); }
    .event .meta { gap: var(--s1); font-size:12px; }
    .event .meta .mi:nth-child(3) { display:none; }   /* "Gqeberha · MEDAI × Datamind Labs" */
    .countdown { gap: var(--s1); margin: var(--s1) 0; }
    .cd { padding: var(--s1) var(--s2); }
    .cd b { font-size:13px; }
    .cd span { font-size:8px; }
  }
  @media (max-height: 320px) {
    .side { position: static; max-height: none; }
    .side > .panel:last-child { overflow-y: visible; }
  }

  /* Mobile */
  .tabbar, .fab { display:none; }
  @media (max-width: 900px) {
    .shell { grid-template-columns: 1fr; padding:var(--s4); }
    .rail, .side { display:none; }
    .search { display:none; }
    /* Installed as a PWA there is no browser chrome: viewport-fit=cover lets the
       layout viewport run under the status bar, so the band insets itself or the
       brand renders beneath the clock. env() is 0 in a tab and on desktop. */
    .topbar { padding: calc(var(--s3) + env(safe-area-inset-top, 0px)) var(--s4); }
    /* Stop the account buttons breaking mid-label: "Sign in" was wrapping to
       "Sign" / "in" once the band ran out of room at phone width. */
    .band-end .btn { white-space: nowrap; }
    /* The island is desktop navigation; below this width the .tabbar takes
       over, and two nav controls doing the same job would be worse than one. */
    .dock { display: none; }
    .feed-head h2 { font-size:20px; }
    /* Mobile chrome — "island": 02 Glassmorphism material in dock form factor.
       Detached from the screen edges (left/right/bottom insets) rather than welded
       to the bottom, so it reads as a floating capsule of frosted glass.
       See ARCHITECTURE.md §10 for the decision and the reference sheet. */
    .tabbar {
      display:flex; position:fixed; z-index:50;
      left:var(--s3); right:var(--s3);
      bottom:calc(var(--s3) + env(safe-area-inset-bottom, 0px));
      padding:6px; gap:2px; justify-content:space-around;
      border-radius:999px;
      background:var(--surface);                                     /* fallback */
      background:color-mix(in srgb, var(--surface) 72%, transparent);
      -webkit-backdrop-filter:blur(14px) saturate(140%);
      backdrop-filter:blur(14px) saturate(140%);
      border:1px solid var(--hair);
      box-shadow:var(--shadow);
      padding-bottom:calc(6px + env(safe-area-inset-bottom, 0px));
    }
    /* The sheet's rule, treated as an acceptance criterion: >=48x48 tap targets.
       The old bar was a 20px icon in var(--s2) padding — well under this. */
    .tabbar a {
      flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
      gap:2px; min-height:48px; min-width:48px; padding:6px 4px;
      color:var(--muted); text-decoration:none; font-size:10px; font-weight:500;
      border-radius:999px;
      transition:color .18s ease, background-color .18s ease;
    }
    .tabbar a .ic { transition:transform .18s ease; }
    .tabbar a:active .ic { transform:scale(.9); }
    .tabbar a.active { color:var(--accent); background:var(--accent-soft); }
    .fab {
      display:grid; place-items:center; position:fixed; z-index:51;
      bottom:calc(var(--s3) + env(safe-area-inset-bottom, 0px) + 66px); right:var(--s4);
      width:56px; height:56px; border-radius:50%; background:var(--ink); color:var(--bg);
      box-shadow:var(--shadow-border-hover); border:0; cursor:pointer;
    }
    .hide-sm { display:none; }
    body { padding-bottom:calc(var(--s8) + 48px); }
  }

  /* --- Account pages: signup / login / profile ------------------------------ */
  a.brand { text-decoration:none; color:inherit; }
  a.profile { text-decoration:none; color:inherit; display:block; }
  .inline { display:inline; margin:0; }

  .auth { display:grid; place-items:center; padding:var(--s6) var(--s4) var(--s8); min-height:70vh; }
  .auth-card {
    width:100%; max-width:430px;
    background:var(--surface);                                       /* fallback */
    background:color-mix(in srgb, var(--surface) 88%, transparent);
    -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
    border:1px solid var(--hair); border-radius:var(--radius);
    box-shadow:var(--shadow); padding:var(--s6);
  }
  .auth-card h1 { font-family:'Satoshi'; font-size:26px; letter-spacing:-.02em; margin:0 0 var(--s1); }
  .auth-card .sub { color:var(--muted); font-size:13px; margin:0 0 var(--s5); line-height:1.5; }

  .field { display:block; margin-bottom:var(--s4); }
  .field > span:first-child {
    display:block; font-size:11px; font-weight:600; color:var(--muted);
    text-transform:uppercase; letter-spacing:.06em; margin-bottom:var(--s2);
  }
  .field input, .field textarea {
    width:100%; font:inherit; font-size:15px; color:var(--ink);
    background:var(--bg); border:1px solid var(--hair); border-radius:var(--r-sm);
    padding:12px 14px; min-height:48px;       /* 48px target, same rule as the island */
  }
  .field textarea { min-height:110px; resize:vertical; }
  .field input:focus, .field textarea:focus {
    outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft);
  }
  .field em.err { display:block; font-size:12px; font-style:normal; color:#B3261E; margin-top:var(--s2); }
  .helptext { display:block; font-size:11px; color:var(--muted); margin-top:var(--s2); line-height:1.5; }
  .helptext ul { margin:var(--s1) 0 0; padding-left:var(--s4); }

  .btn.wide { width:100%; justify-content:center; min-height:48px; }

  .msg { border-radius:var(--r-sm); padding:var(--s3) var(--s4); font-size:13px; margin-bottom:var(--s4); }
  .msg.err { background:#FDECEA; color:#8C1D18; border:1px solid #F5C6C1; }
  .msg.ok  { background:#E8F5E9; color:#1B5E20; border:1px solid #BFE3C2; }
  .auth-card .alt { font-size:13px; color:var(--muted); margin-top:var(--s5); text-align:center; }

  [data-theme="dark"] .field input, [data-theme="dark"] .field textarea { background:var(--surface); }
  [data-theme="dark"] .msg.err { background:#3A1D1A; color:#FFB4AB; border-color:#5C2A26; }
  [data-theme="dark"] .msg.ok  { background:#1B2E1C; color:#A5D6A7; border-color:#2E4A30; }
