/* CatchARidePDX — additional themes.
 *
 * Linked after styles.css so a block here overrides the base ramp for its
 * own [data-theme]. Every theme states the same custom-property contract the
 * originals do, --map-filter included: the Leaflet OSM tiles are light by
 * default and a dark theme that forgets the filter reads as a broken map.
 *
 * Text and state colours are generated to clear WCAG AA against every
 * background in their own ramp (4.5:1 body and state pills, 3:1 accent),
 * measured rather than eyeballed. Canonical palettes are kept where they
 * already pass and lifted in lightness only where they did not — hue and
 * saturation are held, so Gruvbox still reads as Gruvbox.
 * Regenerate/verify with scratchpad/contrast.py.
 */


/* ---- Dark ---- */
[data-theme="gruvbox-dark"]{--bg-0:#1d2021;--bg-1:#282828;--bg-2:#32302f;--surface:#282828;--surface-hover:#3c3836;--text-0:#fbf1c7;--text-1:#ebdbb2;--text-2:#bdae93;--accent:#fe8019;--accent-dim:rgba(254,128,25,.18);--green:#b8bb26;--yellow:#fabd2f;--red:#fc6755;--blue:#83a598;--glass:rgba(40,40,40,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(170deg) sepia(.25) saturate(1.25) brightness(.82)}
[data-theme="catppuccin-mocha"]{--bg-0:#1e1e2e;--bg-1:#181825;--bg-2:#313244;--surface:#1e1e2e;--surface-hover:#45475a;--text-0:#cdd6f4;--text-1:#bac2de;--text-2:#a6adc8;--accent:#cba6f7;--accent-dim:rgba(203,166,247,.18);--green:#a6e3a1;--yellow:#f9e2af;--red:#f38ba8;--blue:#89b4fa;--glass:rgba(24,24,37,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(185deg) saturate(.85) brightness(.86) contrast(.92)}
[data-theme="tokyo-night"]{--bg-0:#1a1b26;--bg-1:#16161e;--bg-2:#24283b;--surface:#1f2335;--surface-hover:#2f3549;--text-0:#c0caf5;--text-1:#a9b1d6;--text-2:#9aa5ce;--accent:#7aa2f7;--accent-dim:rgba(122,162,247,.18);--green:#9ece6a;--yellow:#e0af68;--red:#f7768e;--blue:#7dcfff;--glass:rgba(22,22,30,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(195deg) saturate(1.1) brightness(.8) contrast(.95)}
[data-theme="one-dark"]{--bg-0:#282c34;--bg-1:#21252b;--bg-2:#333842;--surface:#2c313a;--surface-hover:#3e4451;--text-0:#dcdfe4;--text-1:#c8ccd4;--text-2:#abb2bf;--accent:#61afef;--accent-dim:rgba(97,175,239,.18);--green:#98c379;--yellow:#e5c07b;--red:#e5858c;--blue:#56b6c2;--glass:rgba(33,37,43,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(180deg) brightness(.84) contrast(.92)}
[data-theme="everforest-dark"]{--bg-0:#2d353b;--bg-1:#272e33;--bg-2:#374145;--surface:#2d353b;--surface-hover:#414b50;--text-0:#d3c6aa;--text-1:#c5b596;--text-2:#b8a88d;--accent:#a7c080;--accent-dim:rgba(167,192,128,.18);--green:#83c092;--yellow:#dbbc7f;--red:#ea9293;--blue:#7fbbb3;--glass:rgba(39,46,51,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(155deg) sepia(.2) saturate(1.1) brightness(.82)}
[data-theme="midnight"]{--bg-0:#04060f;--bg-1:#080d1c;--bg-2:#0f1830;--surface:#0b1226;--surface-hover:#152040;--text-0:#e8eeff;--text-1:#c3d0ee;--text-2:#94a6cc;--accent:#5b8cff;--accent-dim:rgba(91,140,255,.18);--green:#3ddc97;--yellow:#ffc857;--red:#ff6b6b;--blue:#4cc9f0;--glass:rgba(8,13,28,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(205deg) saturate(1.2) brightness(.78) contrast(1.05)}

/* ---- Vivid ---- */
[data-theme="amber-crt"]{--bg-0:#0d0900;--bg-1:#140e00;--bg-2:#1c1400;--surface:#171000;--surface-hover:#241900;--text-0:#ffb000;--text-1:#ffc04d;--text-2:#d99500;--accent:#ffb000;--accent-dim:rgba(255,176,0,.18);--green:#ffcf40;--yellow:#ffd966;--red:#ff8a3d;--blue:#ffd08a;--glass:rgba(20,14,0,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) grayscale(1) sepia(1) hue-rotate(345deg) saturate(3) brightness(.68)}

/* ---- Dark ---- */
[data-theme="plum"]{--bg-0:#160d1a;--bg-1:#1d1122;--bg-2:#2a1a31;--surface:#21142a;--surface-hover:#35213e;--text-0:#f6e9fb;--text-1:#dfc4ea;--text-2:#bd94cf;--accent:#e879f9;--accent-dim:rgba(232,121,249,.18);--green:#6ee7b7;--yellow:#fcd34d;--red:#fb7185;--blue:#a5b4fc;--glass:rgba(29,17,34,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) hue-rotate(230deg) saturate(1.25) brightness(.82)}

/* ---- Accessible ---- */
[data-theme="carbon"]{--bg-0:#0b0b0b;--bg-1:#121212;--bg-2:#1c1c1c;--surface:#161616;--surface-hover:#242424;--text-0:#ffffff;--text-1:#e4e4e4;--text-2:#b9b9b9;--accent:#d0d0d0;--accent-dim:rgba(208,208,208,.18);--green:#c8c8c8;--yellow:#dedede;--red:#f0f0f0;--blue:#bcbcbc;--glass:rgba(18,18,18,.85);--glass-border:rgba(255,255,255,.10);--border:rgba(255,255,255,.10);--map-filter:invert(1) grayscale(1) contrast(1.05) brightness(.9)}

/* ---- Light ---- */
[data-theme="gruvbox-light"]{--bg-0:#fbf1c7;--bg-1:#f2e5bc;--bg-2:#ebdbb2;--surface:#fdf6d8;--surface-hover:#ecdfb0;--text-0:#282828;--text-1:#3c3836;--text-2:#504945;--accent:#af3a03;--accent-dim:rgba(175,58,3,.14);--green:#68630c;--yellow:#86570f;--red:#9d0006;--blue:#076678;--glass:rgba(242,229,188,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:sepia(.3) saturate(.9) brightness(1.02)}
[data-theme="catppuccin-latte"]{--bg-0:#eff1f5;--bg-1:#e6e9ef;--bg-2:#dce0e8;--surface:#ffffff;--surface-hover:#e6e9ef;--text-0:#4c4f69;--text-1:#5c5f77;--text-2:#606276;--accent:#8839ef;--accent-dim:rgba(136,57,239,.14);--green:#2d711e;--yellow:#8b5812;--red:#c60e36;--blue:#0a55ea;--glass:rgba(230,233,239,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:saturate(.92) brightness(1.02)}
[data-theme="everforest-light"]{--bg-0:#fdf6e3;--bg-1:#f4f0d9;--bg-2:#efebd4;--surface:#fffbef;--surface-hover:#e6e2cc;--text-0:#5c6a72;--text-1:#4f585e;--text-2:#5c6a72;--accent:#7d8f01;--accent-dim:rgba(125,143,1,.14);--green:#267759;--yellow:#8a6300;--red:#d50c09;--blue:#2c7096;--glass:rgba(244,240,217,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:sepia(.22) saturate(.85) brightness(1.02)}
[data-theme="sepia"]{--bg-0:#f4ecd8;--bg-1:#ece2ca;--bg-2:#e3d7ba;--surface:#fbf5e6;--surface-hover:#e3d7ba;--text-0:#2b2016;--text-1:#433424;--text-2:#5b4636;--accent:#8b4513;--accent-dim:rgba(139,69,19,.14);--green:#476729;--yellow:#745b00;--red:#a52a2a;--blue:#2a5a8a;--glass:rgba(236,226,202,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:sepia(.55) saturate(.75) contrast(1.05)}

/* ---- Accessible ---- */
[data-theme="eink"]{--bg-0:#ffffff;--bg-1:#f4f4f4;--bg-2:#e9e9e9;--surface:#ffffff;--surface-hover:#ebebeb;--text-0:#000000;--text-1:#1f1f1f;--text-2:#3d3d3d;--accent:#2b2b2b;--accent-dim:rgba(43,43,43,.14);--green:#333333;--yellow:#444444;--red:#1a1a1a;--blue:#2f2f2f;--glass:rgba(244,244,244,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:grayscale(1) contrast(1.35) brightness(1.05)}

/* ---- Light ---- */
[data-theme="sandstone"]{--bg-0:#faf4ea;--bg-1:#f3ead9;--bg-2:#e9dcc6;--surface:#fffaf2;--surface-hover:#e9dcc6;--text-0:#33291d;--text-1:#4a3c2b;--text-2:#6b5842;--accent:#a0522d;--accent-dim:rgba(160,82,45,.14);--green:#466b3b;--yellow:#865900;--red:#b32424;--blue:#1f5f8b;--glass:rgba(243,234,217,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:sepia(.35) saturate(.85) brightness(1.03)}
[data-theme="nord-light"]{--bg-0:#eceff4;--bg-1:#e5e9f0;--bg-2:#d8dee9;--surface:#ffffff;--surface-hover:#dfe4ee;--text-0:#2e3440;--text-1:#3b4252;--text-2:#4c566a;--accent:#5d80ac;--accent-dim:rgba(93,128,172,.14);--green:#456b37;--yellow:#825b00;--red:#a3424b;--blue:#386784;--glass:rgba(229,233,240,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:saturate(.85) brightness(1.03) hue-rotate(-6deg)}

/* ---- Accessible ---- */
[data-theme="contrast-light"]{--bg-0:#ffffff;--bg-1:#ffffff;--bg-2:#f0f0f0;--surface:#ffffff;--surface-hover:#e8e8e8;--text-0:#000000;--text-1:#000000;--text-2:#1a1a1a;--accent:#0000cc;--accent-dim:rgba(0,0,204,.14);--green:#006600;--yellow:#7a4b00;--red:#b30000;--blue:#0044cc;--glass:rgba(255,255,255,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:grayscale(1) contrast(1.5) brightness(1.08)}
[data-theme="large-type"]{--bg-0:#fffdf7;--bg-1:#fff8e8;--bg-2:#f4ecd8;--surface:#ffffff;--surface-hover:#f4ecd8;--text-0:#141414;--text-1:#242424;--text-2:#3b3b3b;--accent:#7b3fbf;--accent-dim:rgba(123,63,191,.14);--green:#1c6b2e;--yellow:#7a4b00;--red:#a31212;--blue:#12457a;--glass:rgba(255,248,232,.85);--glass-border:rgba(0,0,0,.12);--border:rgba(0,0,0,.12);--map-filter:saturate(.9) contrast(1.15) brightness(1.03);font-size:112.5%;letter-spacing:.005em;line-height:1.6}


/* ==========================================================================
   COMPONENT STYLES for markup introduced by app.js / analytics.js
   ==========================================================================
   Only selectors styles.css does not define. Everything the designer has since
   picked up — .search-wrap, .quick-add, .sort-select, .map-hint, .settings-*,
   .notif-volume-*, .arr-meta, .cd-map-toggle, .sr-only, .ico — was removed from
   here: themes.css loads last, so keeping a copy would have overridden their
   version with this one. Add to styles.css rather than here once a selector is
   theirs.

   Colours come only from the token contract, so all 32 themes are covered
   without per-theme rules. Prefers the designer's newer tokens (--tint,
   --text-muted, --ink-accent, --on-accent, --sp-*, --fs-*) with a fallback, so
   this file also works if it is ever loaded on its own.
   ========================================================================== */

/* Arrival row metadata -----------------------------------------------------
   .arr-times used to hold one concatenated string ("9:52 PM (sched 9:50 PM) ·
   17% full · detour"), which wrapped to a second line once long enough, so rows
   were 56px or 62px tall depending on content. The crowding figure and the
   detour flag are their own chips now and .arr-times holds only the clock; the
   scheduled time is what gives way at phone widths, being the least
   load-bearing part. */
.arr-sched{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:var(--fs-200,11px);color:var(--text-muted,var(--text-2))}
.arr-chip{flex:none;font-size:var(--fs-100,9.5px);font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;padding:2px 6px;border-radius:var(--radius-full);
  background:var(--tint,var(--bg-2));color:var(--text-muted,var(--text-2));
  white-space:nowrap;line-height:1.35}
/* Keep % readable — uppercase on "17% FULL" looks like a unit error. */
.arr-chip-load{text-transform:none;letter-spacing:0}
.arr-chip-detour{background:var(--accent-dim);color:var(--ink-accent,var(--accent))}

/* Phone topbar: five controls in one row squeezed the search field to ~100px.
   The wordmark is the only one of them carrying no function, so it is what
   goes; #brandLive keeps its aria-label, so status still reads. */
@media(max-width:430px){
  .brand-name-collapsible{display:none}
  .arr-sched{display:none}
}

/* Shared saved-stop control ----------------------------------------------- */
.savectl{display:inline-flex;align-items:center;gap:5px;
  background:var(--tint,var(--bg-2));border:1px solid var(--border);
  color:var(--text-1);border-radius:var(--radius-full);
  padding:5px 11px;font-family:inherit;font-size:11.5px;font-weight:600;
  cursor:pointer;line-height:1.2}
.savectl svg{width:13px;height:13px;flex:none}
.savectl:hover{border-color:var(--accent);color:var(--ink-accent,var(--accent));background:var(--accent-dim)}
.savectl.on{color:var(--ink-yellow,var(--yellow));border-color:var(--yellow)}
.savectl.sm{padding:3px 7px;font-size:11px}
.savectl.sm svg{width:12px;height:12px}

/* Countdown card head ----------------------------------------------------- */
.cd-stop-row{display:flex;align-items:flex-start;gap:10px}
.cd-stop-row .cd-stop{flex:1;min-width:0}

/* Permanent labels on the countdown mini-map ------------------------------ */
.leaflet-tooltip.cd-tip{background:var(--surface);color:var(--text-0);
  border:1px solid var(--border);border-radius:var(--radius-sm);
  box-shadow:0 2px 10px rgba(0,0,0,.28);font-family:inherit;font-size:10.5px;
  line-height:1.35;padding:4px 8px;font-weight:500;
  /* Wraps rather than running off: nowrap let a long destination sign extend
     past the 250px-tall map container and get clipped mid-word. */
  white-space:normal;max-width:148px;text-align:center}
.leaflet-tooltip.cd-tip b{font-weight:700}
.leaflet-tooltip.cd-tip::before{display:none}
.leaflet-tooltip.cd-tip-stop{border-color:var(--green)}
.leaflet-tooltip.cd-tip-bus{border-color:var(--accent)}

/* Stops on the map tab ---------------------------------------------------- */
.map-stop-dot{fill:var(--accent);stroke:var(--surface);cursor:pointer}
.map-stop-dot:hover{fill:var(--yellow)}
.leaflet-tooltip.map-stop-label{background:var(--glass);color:var(--text-0);
  border:1px solid var(--glass-border);border-radius:5px;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  font-family:inherit;font-size:10px;font-weight:500;line-height:1.2;
  padding:2px 6px;box-shadow:none;max-width:190px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.leaflet-tooltip.map-stop-label b{font-family:var(--font-mono);font-weight:600;
  color:var(--ink-accent,var(--accent))}
.leaflet-tooltip.map-stop-label::before{display:none}
/* Dots appear at z15, names one zoom later: at z15 a downtown viewport holds
   ~120 stops whose labels overlap into an unreadable band. */
.hide-stop-labels .leaflet-tooltip.map-stop-label{display:none}
.map-card-actions{margin-top:8px;display:flex;justify-content:flex-end}
.map-card-save{margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
.map-card-save-stop{font-size:12px;font-weight:600;color:var(--text-0)}
.map-card-save-note{font-size:10.5px;color:var(--text-muted,var(--text-2));line-height:1.4;margin-top:2px}
.map-stop-row .savectl{margin-left:6px}

/* Route breakout — stops on this route ------------------------------------ */
.rm-subhead{font-size:12px;font-weight:700;text-transform:uppercase;
  letter-spacing:.05em;color:var(--text-muted,var(--text-2));margin:14px 0 8px}
.rm-note{font-size:11px;color:var(--text-muted,var(--text-2));line-height:1.45;margin-top:6px}
.rm-stop-list{display:flex;flex-direction:column;gap:5px;max-height:190px;overflow-y:auto}
.rm-stop-row{display:flex;align-items:center;gap:8px;padding:6px 10px;
  background:var(--tint,var(--bg-2));border-radius:6px;font-size:12px}
.rm-stop-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rm-stop-id{font-family:var(--font-mono);font-size:11px;color:var(--text-muted,var(--text-2))}

/* Today stat cards + breakout internals ----------------------------------- */
.tile.stat-card{position:relative;cursor:pointer;
  transition:border-color .15s var(--ease-out),transform .15s var(--ease-out)}
.tile.stat-card:hover{border-color:var(--accent);transform:translateY(-1px)}
.stat-more{position:absolute;top:10px;right:11px;color:var(--text-muted,var(--text-2));
  font-size:14px;line-height:1}
.tile.stat-card:hover .stat-more{color:var(--ink-accent,var(--accent))}
.stat-list{display:flex;flex-direction:column;gap:5px;max-height:260px;overflow-y:auto}
.stat-row{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:7px 10px;background:var(--tint,var(--bg-2));border-radius:6px;font-size:12px}
.stat-row-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stat-row-value{flex:none;color:var(--text-1);font-weight:600}
.stat-row.is-drill{cursor:pointer}
.stat-row.is-drill:hover{background:var(--surface-hover);outline:1px solid var(--accent)}
.stat-note{font-size:11px;color:var(--text-muted,var(--text-2));line-height:1.5;margin-top:10px}
.stat-provenance{margin-bottom:16px}
.stat-hist{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.stat-hist-row{display:flex;align-items:center;gap:8px;font-size:11.5px}
.stat-hist-label{flex:0 0 40%;color:var(--text-1)}
.stat-hist-bar{flex:1;height:9px;background:var(--tint,var(--bg-2));
  border-radius:var(--radius-full);overflow:hidden}
.stat-hist-bar>span{display:block;height:100%;background:var(--accent);border-radius:inherit}
.stat-hist-n{flex:none;min-width:2.5em;text-align:right;font-family:var(--font-mono);
  color:var(--text-muted,var(--text-2))}

/* Notification rows: name over description ------------------------------- */
.notif-toggle-name{font-size:12px;font-weight:600;color:var(--text-0)}
.notif-toggle-desc{font-size:10.5px;color:var(--text-muted,var(--text-2));line-height:1.3}
/* Faded-but-operable was worse than disabled: it still took focus and still
   read as available. The input carries `disabled`; this only dims the row. */
.notif-volume-row.is-disabled{opacity:.55}
.notif-volume-row.is-disabled .notif-volume{cursor:not-allowed}

/* Analytics provenance line ---------------------------------------------- */
.analytics-provenance{font-size:11px;color:var(--text-muted,var(--text-2));
  line-height:1.5;margin:10px 0 0;max-width:72ch}

/* Search results: stated when the centre is a fallback, not the user ------ */
.res-banner{padding:9px 12px;font-size:11.5px;line-height:1.45;color:var(--text-1);
  background:var(--accent-dim);border-radius:var(--radius-sm);margin-bottom:6px;list-style:none}

/* No focus-ring block here: styles.css covers every focusable element with
   :where(a,button,input,select,textarea,summary,[tabindex]):focus-visible, so
   each element made focusable in this pass picks that up by carrying tabindex.
   A copy here would only override the designer's ring with a worse one. */

/* The mini-map toggle sits in a card-width button; its label must not wrap. */
.cd-map-toggle-txt{white-space:nowrap}


/* Themes above often omit --shadow-color; shadows then fall back to the base
 * dark token on light themes. Restate by family so elevation stays visible. */
[data-theme="gruvbox-dark"],[data-theme="catppuccin-mocha"],[data-theme="tokyo-night"],
[data-theme="one-dark"],[data-theme="everforest-dark"],[data-theme="midnight"],
[data-theme="amber-crt"],[data-theme="plum"],[data-theme="carbon"],
[data-theme="nord"],[data-theme="dracula"],[data-theme="monokai"],
[data-theme="solarized-dark"],[data-theme="ayu-dark"],[data-theme="material-dark"]{
  --shadow-color:230 45% 2%;
}
[data-theme="gruvbox-light"],[data-theme="catppuccin-latte"],[data-theme="everforest-light"],
[data-theme="sepia"],[data-theme="solarized"],[data-theme="paper"],
[data-theme="nord-light"],[data-theme="ayu-light"],
[data-theme="sandstone"],[data-theme="contrast-light"],[data-theme="eink"],
[data-theme="large-type"]{
  --shadow-color:230 40% 28%;
}

/* These themes set --text-0 equal to --accent, so --ring:var(--text-0) would
 * make the focus ring invisible against accent-filled chrome. */
[data-theme="amber-crt"],[data-theme="terminal"]{
  --ring:#ffffff;
  --focus:var(--ring);
}
