/* src/styles/legislative-calendar.css */
  :root{
    --container-max:1240px;
    --container-pad:24px;
    /* Ink (dark surfaces) */
    --ink-950:#05011F;
    --ink-900:#0A0438;
    /* Brand */
    --raspberry-500:#E60058;
    --raspberry-600:#99003B;
    --raspberry-300:#F280AB;
    --raspberry-50:#FEF2F7;
    --ultra-500:#4002FF;
    --ultra-600:#2B01AA;
    --ultra-700:#200180;
    --ultra-50:#ECE6FF;
    /* Slate neutrals */
    --slate-900:#0F172A;
    --slate-800:#1E293B;
    --slate-700:#334155;
    --slate-600:#475569;
    --slate-500:#64748B;
    --slate-400:#94A3B8;
    --slate-200:#E2E8F0;
    --slate-100:#F1F5F9;
    --slate-50:#F8FAFC;
    --white-muted:rgba(255,255,255,.55);
    --white-faint:rgba(255,255,255,.12);
    --white-hairline:rgba(255,255,255,.08);
    /* Categorical tag colors (bg=50, text=700) — used for topic/category
       chips, distinct from semantic status colors */
    --amber-50:#FFFBE8; --amber-600:#D97706; --amber-700:#B45309;
    --sky-50:#F0F9FF; --sky-600:#0284C7; --sky-700:#0369A1;
    --violet-50:#F5F3FF; --violet-600:#7C3AED; --violet-700:#6D28D9;
    --teal-600:#0D9488; --teal-700:#0F766E;
    --indigo-50:#EEF2FF; --indigo-600:#4F46E5; --indigo-700:#4338CA;
    --emerald-50:#ECFDF5; --emerald-100:#D1FAE5; --emerald-600:#059669; --emerald-700:#047857;
    /* Radius scale */
    --radius-sm:4px; --radius-md:6px; --radius-lg:8px;
    --radius-xl:10px; --radius-2xl:14px; --radius-full:9999px;
    /* Elevation */
    --elev-1:0 1px 0 rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.06);
    --elev-2:0 2px 0 rgba(15,23,42,.04), 0 12px 32px -12px rgba(15,23,42,.18), 0 4px 8px -4px rgba(15,23,42,.08);
  }
  *{box-sizing:border-box;}
  body{
    margin:0;
    background:var(--ink-950);
    color:var(--slate-200);
    font-family:'Satoshi',sans-serif;
    -webkit-font-smoothing:antialiased;
  }
  .page{max-width:var(--container-max);margin:0 auto;padding:0 var(--container-pad) 80px;}
  @media (max-width:480px){
    .page{padding-left:16px;padding-right:16px;}
  }

  /* HEADER */
  .hero{
    margin-bottom:20px;
  }
  .hero-inner{max-width:var(--container-max);margin:0 auto;padding:56px var(--container-pad) 40px;}
  .eyebrow{
    font-family:'Satoshi',sans-serif;
    font-size:12px;
    letter-spacing:.15em;
    text-transform:uppercase;
    color:var(--raspberry-300);
    margin-bottom:14px;
  }
  .hero-inner h1{max-width:1100px !important;}
  h1{
    font-family:'Mont','Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:clamp(26px,4.6vw,44px);
    line-height:1.05;
    max-width:1100px;
    margin:0 0 14px;
    letter-spacing:-0.025em;
    color:#fff;
  }
  .hero p{
    max-width:700px;
    color:var(--white-muted);
    font-size:15px;
    line-height:1.65;
    margin:0;
  }
  .hero p.hero-updated{
    margin-top:18px;
    padding-top:14px;
    border-top:1px solid var(--white-hairline);
    font-size:12.5px;
    color:var(--white-muted);
    opacity:.75;
  }
  .hero-signup{
    display:flex;
    flex-wrap:wrap;
    gap:12px;
    max-width:700px;
    margin-top:22px;
  }
  .hero-signup-input{
    flex:1;
    min-width:220px;
    background:var(--white-faint);
    border:1px solid var(--white-hairline);
    border-radius:var(--radius-lg);
    padding:12px 18px;
    font-family:'Satoshi',sans-serif;
    font-size:14px;
    color:#fff;
  }
  .hero-signup-input::placeholder{color:var(--white-muted);}
  .hero-signup-input:focus{outline:2px solid var(--raspberry-500);outline-offset:1px;}
  .hero-signup-btn{
    flex:none;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    line-height:1;
    background:var(--raspberry-500);
    color:#fff;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:14px;
    border:none;
    padding:14px 26px;
    border-radius:var(--radius-full);
    cursor:pointer;
    box-shadow:0 6px 20px rgba(230,0,88,.35);
    transition:background .15s ease;
  }
  .hero-signup-btn:hover{background:var(--raspberry-600);}

  /* CONTROLS */
  .controls{
    display:flex;
    flex-wrap:wrap;
    gap:12px;
    align-items:center;
    margin-bottom:24px;
  }
  .view-toggle{
    display:flex;
    background:var(--white-faint);
    border:1px solid var(--white-hairline);
    border-radius:var(--radius-full);
    padding:3px;
  }
  .view-toggle button{
    border:none;
    background:transparent;
    padding:8px 18px;
    font-family:'Satoshi',sans-serif;
    font-size:13px;
    font-weight:700;
    color:var(--white-muted);
    border-radius:var(--radius-full);
    cursor:pointer;
    transition:all .15s ease;
  }
  .view-toggle button:hover:not(.active){
    color:#fff;
    background:rgba(255,255,255,.08);
  }
  .view-toggle button.active{
    background:var(--raspberry-500);
    color:#fff;
  }
  .search-wrap{position:relative;flex:1 1 180px;max-width:260px;min-width:140px;}
  .search-wrap input{
    width:100%;
    padding:9px 14px 9px 34px;
    border-radius:var(--radius-full);
    border:1px solid var(--slate-200);
    background:#fff;
    font-family:'Satoshi',sans-serif;
    font-size:14px;
    color:var(--slate-900);
  }
  .search-wrap input:focus{outline:2px solid var(--ultra-500);outline-offset:1px;}
  .search-wrap svg{
    position:absolute;left:12px;top:50%;transform:translateY(-50%);
    width:14px;height:14px;stroke:var(--slate-500);
  }
  /* Filters are grouped in their own visually distinct container —
     separate from the view toggle (which switches page mode, not what's
     shown) so the two don't blend together and read as one confusing
     control cluster. */
  /* Stat summary: sits above the tab switcher (not inside either tab)
     because "who's in session right now" is relevant no matter which
     detailed view someone picks next — burying it inside one tab would
     mean anyone landing on the other tab first never sees it. */
  .section-title{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:24px;
    color:#fff;
    margin:0 0 16px;
  }
  .stat-summary{
    max-width:1080px;
    margin-bottom:28px;
  }
  .stat-card--unified{
    display:grid;
    grid-template-columns:1.3fr 1fr;
    gap:20px;
  }
  @media (max-width:720px){ .stat-card--unified{grid-template-columns:1fr;} }
  /* No divider line anymore — everything here is already contained
     inside its own box (see below), so a plain border between the two
     columns was a redundant second separator doing nothing the boxes
     don't already do. */
  .stat-col-left{
    position:relative;
    display:flex;
    flex-direction:column;
    padding:14px;
    border-radius:var(--radius-lg);
    /* Genuinely transparent — no fill at all, just lets the parent
       card's own dark background + dot pattern show straight through.
       The gradient ring is a separate pseudo-element (below), not part
       of this element's own background — that's what makes the middle
       actually see-through instead of flooded with color. */
    background:transparent;
  }
  .stat-col-left::before{
    content:"";
    position:absolute;
    inset:0;
    border-radius:inherit;
    padding:1px;
    background:linear-gradient(135deg, var(--emerald-600), var(--ultra-600));
    /* mask-composite "punches out" everything except a 1px ring — this
       is what a flat/low-opacity double-background layering couldn't
       actually do; that approach can only ever dim the fill, never make
       it truly absent. */
    -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite:xor;
    mask-composite:exclude;
    pointer-events:none;
  }
  @media (max-width:720px){ .stat-col-left{padding-bottom:16px;} }
  .stat-col-right{display:flex;flex-direction:column;}
  .stat-inline-head{
    display:flex;
    align-items:center;
    gap:8px;
    margin-bottom:12px;
  }
  .stat-inline-head h4{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:16px;
    line-height:1;
    color:#fff;
    margin:0;
  }
  .stat-inline-head .stat-count{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:400;
    font-size:13px;
    line-height:1;
    color:var(--white-muted);
  }
  .stat-card{
    background:var(--ink-900);
    border:1px solid var(--white-hairline);
    border-radius:var(--radius-xl);
    padding:14px;
  }
  .stat-card-head{
    display:flex;
    align-items:center;
    gap:8px;
    margin-bottom:12px;
  }
  .stat-card-head h3{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:18px;
    line-height:1;
    color:#fff;
    margin:0;
  }
  .stat-card-head .stat-count{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:400;
    font-size:13px;
    line-height:1;
    color:var(--white-muted);
  }
  /* Each group is its own contained sub-card — a real boundary (border +
     faint tint) instead of a line trying to imply separation. Solves the
     "where does one section end and the next begin" problem directly,
     rather than needing color-matched accents to hint at it. */
  .stat-group{
    margin-top:10px;
    padding:14px;
    border-radius:var(--radius-lg);
    border:1px solid transparent;
    /* Double-background trick: one flat fill for the inside (padding-box),
       one gradient for the border itself (border-box) — lets the border
       fade from the group's accent color into the card's own background
       tone instead of being a single flat saturated color all the way
       around, which read as too loud/pronounced. */
    background:
      linear-gradient(rgba(255,255,255,.03), rgba(255,255,255,.03)) padding-box,
      linear-gradient(135deg, var(--group-color, var(--white-hairline)), var(--ink-900) 85%) border-box;
  }
  /* No top margin on the first sub-card — it needs to start flush with
     the top of the column so it aligns with the "In Session" box's
     border on the left, not sit 14px lower than it. */
  .stat-group:first-child{margin-top:0;}
  .stat-group-label{
    display:flex;
    align-items:center;
    gap:6px;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:11px;
    line-height:1;
    text-transform:uppercase;
    letter-spacing:.05em;
    color:#fff;
    margin-bottom:12px;
  }
  .stat-group-label .stat-count{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:400;
    line-height:1;
    text-transform:none;
    letter-spacing:0;
    color:var(--white-muted);
  }
  .stat-chips{display:flex;flex-wrap:wrap;gap:6px;}
  .stat-empty{
    font-family:'Satoshi',sans-serif;
    font-size:12.5px;
    color:var(--white-muted);
    font-style:italic;
  }
  .stat-chip{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:34px;
    height:28px;
    padding:0 8px;
    border-radius:var(--radius-md);
    font-family:'JetBrains Mono',monospace;
    font-weight:700;
    font-size:11px;
    letter-spacing:.02em;
    cursor:pointer;
    border:none;
    transition:transform .12s ease, box-shadow .12s ease;
  }
  .stat-chip:hover{transform:translateY(-1px);box-shadow:0 4px 10px rgba(0,0,0,.25);}
  .stat-chip.chip-session{background:var(--emerald-600);color:#fff;}
  .stat-chip.chip-special{background:var(--raspberry-500);color:#fff;}
  .stat-chip.chip-soon{background:var(--emerald-100);color:var(--emerald-700);}
  .stat-chip.chip-urgent{background:#FEF3E2;color:var(--amber-700);}

  /* Hierarchy: "In Session" is the headline card (brighter border, faint
     emerald-tinted dot pattern) — everything else is secondary context,
     one shared card with three smaller labeled groups instead of
     competing for the same visual weight. */
  .stat-card{position:relative;overflow:hidden;}
  .stat-card::before{
    content:"";
    position:absolute;
    inset:0;
    background-image:radial-gradient(circle, rgba(255,255,255,.06) 1px, transparent 1px);
    background-size:14px 14px;
    pointer-events:none;
  }
  .stat-card-head, .stat-col-left, .stat-col-right, .stat-inline-head, .stat-group, .stat-chips, .stat-empty{position:relative;}
  /* Year-at-a-glance density mini-chart — fills the left column with
     something genuinely useful on days when the live "in session" count
     is small, rather than leaving dead space or padding around a number
     that's just naturally going to be low most days. */
  .density-chart-wrap{margin-top:auto;padding-top:16px;}
  .density-chart-title{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:10.5px;
    text-transform:uppercase;
    letter-spacing:.05em;
    color:var(--white-muted);
    margin-bottom:8px;
  }
  .density-chart{
    display:flex;
    align-items:flex-end;
    justify-content:flex-start;
    gap:6px;
    height:56px;
  }
  .density-bar{
    flex:1;
    max-width:32px;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:flex-end;
    height:100%;
  }
  .density-bar-fill{
    width:100%;
    border-radius:2px 2px 0 0;
    background:linear-gradient(180deg, #34D399 0%, var(--emerald-600) 100%);
    min-height:2px;
  }
  .density-bar-label{
    margin-top:4px;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:9px;
    color:var(--white-muted);
  }
  .stat-icon{
    display:inline-flex;
    width:15px;height:15px;
    flex:none;
  }
  .stat-icon svg{width:100%;height:100%;}
  .stat-card-head .stat-icon{color:var(--emerald-600);}

  /* Shared popover — one element, repositioned per chip on hover/tap,
     rather than a hidden popover duplicated for every chip. */
  .stat-popover{
    display:none;
    position:absolute;
    z-index:20;
    transform:translateX(-50%);
    background:#fff;
    border-radius:var(--radius-md);
    box-shadow:var(--elev-2);
    padding:10px 12px;
    min-width:150px;
    text-align:center;
  }
  .stat-popover-title{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:12.5px;
    color:var(--slate-900);
    margin-bottom:2px;
  }
  .stat-popover-info{
    font-family:'Satoshi',sans-serif;
    font-size:11.5px;
    color:var(--slate-600);
    margin-bottom:8px;
  }
  .stat-popover-jump{
    width:100%;
    border:none;
    background:var(--ultra-600);
    color:#fff;
    font-family:'Satoshi',sans-serif;
    font-weight:700;
    font-size:11.5px;
    padding:6px 10px;
    border-radius:var(--radius-sm);
    cursor:pointer;
  }
  .stat-popover-jump:hover{background:var(--ultra-700);}

  /* Brief highlight when a stat chip jumps the page to a card, so the
     eye actually lands on the right one instead of just "somewhere on
     screen after a scroll." */
  @keyframes jumpPulse{
    0%{box-shadow:0 0 0 0 rgba(64,2,255,.5);}
    100%{box-shadow:0 0 0 10px rgba(64,2,255,0);}
  }
  .jump-highlight{animation:jumpPulse 1s ease-out 2;}

  .control-divider{
    border:none;
    border-top:1px solid var(--white-hairline);
    margin:16px 0;
  }
  .empty-state{
    text-align:center;
    padding:64px 20px;
  }
  .empty-state svg{
    width:36px;height:36px;
    color:var(--white-muted);
    opacity:.5;
    margin-bottom:16px;
  }
  .empty-title{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:17px;
    color:#fff;
    margin-bottom:6px;
  }
  .empty-sub{
    font-family:'Satoshi',sans-serif;
    font-size:13.5px;
    color:var(--white-muted);
  }
  .filter-row{
    display:flex;
    align-items:center;
    gap:8px;
    flex-wrap:wrap;
    margin-bottom:14px;
  }
  .filter-label{
    font-family:'Satoshi',sans-serif;
    font-size:11px;
    font-weight:700;
    text-transform:uppercase;
    letter-spacing:.06em;
    color:var(--white-muted);
    margin-right:4px;
  }
  .chip{
    border:1px solid var(--white-hairline);
    background:var(--white-faint);
    padding:5px 10px;
    border-radius:var(--radius-sm);
    font-family:'Satoshi',sans-serif;
    font-size:12px;
    font-weight:700;
    color:var(--white-muted);
    cursor:pointer;
    white-space:nowrap;
    transition:all .15s ease;
  }
  .chip:hover:not(.active){
    color:#fff;
    background:rgba(255,255,255,.1);
    border-color:rgba(255,255,255,.3);
  }
  .chip.active{
    background:var(--ultra-600);
    border-color:var(--ultra-600);
    color:#fff;
  }
  .result-count{
    font-family:'Satoshi',sans-serif;
    font-size:12px;
    color:var(--white-muted);
    margin-bottom:20px;
  }

  /* MONTH VIEW */
  .month-section{margin-bottom:36px;}
  .month-head{
    position:sticky;
    top:0;
    z-index:5;
    /* Flat fill matching the page background exactly (not a gradient) —
       the header is width-constrained to the content column, not full-
       bleed, so a gradient that shifts color creates a visible boxed
       rectangle with hard left/right edges. A flat fill in the SAME
       color as the page has no edges to see at all. Soft shadow instead
       of a hard border-bottom still stands — it fades out gradually
       rather than doubling up with the date-divider's own line below.*/
    background:var(--ink-950);
    box-shadow:0 8px 12px -8px rgba(0,0,0,.5);
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:12px;
    padding:14px 0 10px;
    margin-bottom:16px;
  }
  .abbr-legend{
    display:flex;
    gap:16px;
    flex-wrap:wrap;
    font-family:'Satoshi',sans-serif;
    font-size:10.5px;
    color:var(--white-muted);
  }
  .abbr-legend b{font-family:'Plus Jakarta Sans',sans-serif;font-weight:700;color:#fff;margin-right:4px;}
  .month-head h2{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:20px;
    letter-spacing:-0.02em;
    margin:0;
    color:#fff;
    display:flex;
    align-items:center;
    gap:10px;
  }
  .month-head h2 svg{
    width:20px;height:20px;
    flex:none;
    stroke:var(--white-muted);
  }
  .month-head h2 .count{
    font-family:'Satoshi',sans-serif;
    font-size:15px;
    font-weight:400;
    color:var(--white-muted);
    margin-left:4px;
  }
  .card-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(320px,1fr));
    gap:16px;
  }
  /* Real bug, previously invisible: minmax(320px,...) is wider than the
     usable width on most phones once you subtract page padding — this
     was masked before by the missing viewport meta tag (phones were
     never actually rendering at their true narrow width), so it never
     visibly overflowed. Now that the tag is fixed, this needs its own
     explicit mobile layout rather than relying on auto-fill to cope. */
  @media (max-width:680px){
    .card-grid{grid-template-columns:1fr;}
  }
  .date-divider{
    grid-column:1 / -1;
    display:flex;
    align-items:center;
    gap:10px;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:12px;
    color:var(--white-muted);
    margin:2px 0;
  }
  .date-divider::after{
    content:"";
    flex:1;
    height:1px;
    background:var(--white-hairline);
  }
  .date-divider:first-child{margin-top:0;}
  /* Live "where am I" readout — bottom, not the left margin (a tall
     narrow left strip forces either rotated text or type too small to
     read). Complements the static inline dividers rather than
     duplicating them: dividers answer "what date is this row",
     this answers "what date am I generally at right now" while
     scrolling fast. */
  .scroll-date-pill{
    position:fixed;
    left:50%;
    bottom:20px;
    transform:translateX(-50%);
    background:var(--ink-900);
    border:1px solid var(--white-hairline);
    color:#fff;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:12.5px;
    padding:8px 16px;
    border-radius:var(--radius-full);
    box-shadow:0 8px 24px rgba(0,0,0,.35);
    z-index:50;
    pointer-events:none;
    opacity:.95;
  }

  .state-card{
    background:#fff;
    border-radius:var(--radius-2xl);
    padding:12px;
    box-shadow:var(--elev-1);
    transition:box-shadow .18s ease, transform .18s ease;
    display:flex;
    flex-direction:column;
    min-height:150px;
  }
  .state-card:hover{box-shadow:var(--elev-2);transform:translateY(-1px);}
  .state-row-top{
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    margin-bottom:8px;
  }
  .state-name{
    display:flex;
    align-items:center;
    gap:6px;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:17px;
    letter-spacing:-0.01em;
    color:var(--slate-900);
  }
  /* Small, muted state code — a lightly tinted pill (no border/stroke)
     tied to each card's own accent, sitting after the name and sized to
     match its line height so it reads as a paired badge, not a
     mismatched floating label. */
  .state-code{
    display:inline-flex;
    align-items:center;
    vertical-align:middle;
    height:20px;
    padding:0 6px;
    border-radius:var(--radius-sm);
    background:var(--slate-100);
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:10.5px;
    line-height:1;
    letter-spacing:.03em;
    color:var(--slate-500);
  }
  /* rgba, not the indigo-50 token — that's the SAME color as the prefile
     card's own background, so the pill was invisible against it. This
     needs to be visibly deeper than whatever card it sits on. */
  .state-card--prefile .state-code{background:rgba(79,70,229,.15);color:var(--indigo-600);}
  .state-card--special .state-code{background:var(--raspberry-50);color:var(--raspberry-500);}
  .badges{display:flex;align-items:center;gap:5px;flex-wrap:wrap;justify-content:flex-end;}
  /* Fixed height + flex-center (not padding-based vertical centering) —
     padding alone kept looking asymmetric top/bottom regardless of the
     numeric values used, because that's a font-metric issue (ascender/
     descender asymmetry), not a padding bug. A fixed height with content
     centered inside it sidesteps that problem regardless of which font
     ends up here. */
  .badge{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    height:20px;
    font-family:'JetBrains Mono',monospace;
    font-size:10px;
    line-height:1;
    text-transform:uppercase;
    letter-spacing:.04em;
    padding:0 8px;
    border-radius:var(--radius-sm);
    font-weight:700;
    border:1px solid transparent;
  }
  .badge.carry{background:var(--violet-50);color:var(--violet-700);border-color:rgba(124,58,237,.25);}
  .badge.complete{background:var(--slate-100);color:var(--slate-500);}
  /* Bold, filled "what kind of card is this" pills — inverted from the
     lighter outlined style used for secondary attributes like "Carries
     '28", so the card TYPE is the first thing that registers, from
     across the room, before anyone reads a single date. Border stays
     transparent (not "none") so the box height matches bordered badges
     like .carry exactly — that mismatch was what caused the misalignment. */
  .badge.prefile-badge{background:var(--indigo-600);color:#fff;}
  /* Session badge is quiet (tinted, not solid) until the session is
     actually happening — green only means "go" once it's true. Solid
     fill + "In Session" label kick in exactly when today falls
     inside the session window, computed in badgesHTML(). */
  .badge.session-badge{background:var(--emerald-100);color:var(--emerald-700);border-color:rgba(5,150,105,.3);}
  .badge.session-badge.active{background:var(--emerald-600);color:#fff;border-color:transparent;}

  /* Prefile card: a heads-up event, not a session span — tinted indigo
     so it reads as a different kind of card at a glance, with no meter
     (there's no reliable window to plot, just a single trigger date).
     Indigo (not amber) specifically so it doesn't collide with amber's
     new job elsewhere on the page: urgency/"act now, running out."
     Prefile is a heads-up, not a deadline-pressure signal — different
     enough in tone that they shouldn't share a color.
     Uses flex + space-between so it stretches to match the session
     card's height in the same grid row without looking stranded. */
  .state-card--prefile{
    background:var(--indigo-50);
  }
  .state-card--prefile .state-name{color:var(--indigo-700);}
  .prefile-body{flex:1;display:flex;flex-direction:column;justify-content:flex-start;padding-top:4px;}
  .prefile-date{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:20px;
    color:var(--slate-900);
    margin-bottom:4px;
  }
  .prefile-copy{
    font-family:'Satoshi',sans-serif;
    font-size:12.5px;
    color:var(--slate-600);
    line-height:1.4;
  }
  .state-card--prefile .days-caption{border-top-color:rgba(79,70,229,.2);}

  /* Special session card: deliberately louder than everything else on
     the page — dark, gradient glow in brand colors, raspberry badge —
     since these are rare, out-of-cycle events that should interrupt the
     normal scan pattern rather than blend into the regular rhythm of
     white session cards and tinted indigo prefile cards. */
  .state-card--special{
    background:#fff;
    box-shadow:var(--elev-1), 0 0 0 1px rgba(230,0,88,.18);
  }
  .state-card--special:hover{
    box-shadow:var(--elev-2), 0 0 0 1px rgba(230,0,88,.25);
  }
  .state-card--special .state-name{color:var(--raspberry-500);}
  .state-card--special .days-caption{border-top-color:rgba(230,0,88,.15);}
  .badge.special-badge{background:var(--raspberry-500);color:#fff;}

  /* Past accordion: reuses .month-head h2's exact heading treatment
     (left-aligned, white, icon + text) so it reads as "one of these
     month headers" rather than a one-off special element — just with
     an archive icon instead of a calendar, a count, and a chevron that
     rotates via the same [aria-expanded] pattern already used for the
     dual-bid caret above. Body visibility uses the native `hidden`
     attribute (set/cleared directly from JS) rather than a CSS class,
     so collapse/expand can't be silently lost to any stylesheet
     processing step — it's plain HTML semantics, not a custom rule. */
  .past-accordion{margin-bottom:36px;}
  .past-accordion__toggle{
    display:flex;
    align-items:center;
    gap:10px;
    width:100%;
    border:none;
    background:transparent;
    padding:14px 0 10px;
    margin-bottom:16px;
    cursor:pointer;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:20px;
    letter-spacing:-0.02em;
    color:#fff;
    text-align:left;
  }
  .past-accordion__toggle svg{
    width:20px;height:20px;
    flex:none;
    stroke:var(--white-muted);
  }
  .past-accordion__toggle .count{
    font-family:'Satoshi',sans-serif;
    font-size:15px;
    font-weight:400;
    color:var(--white-muted);
    margin-left:-2px;
  }
  .past-accordion__chevron{
    transition:transform .15s ease;
  }
  .past-accordion__toggle[aria-expanded="true"] .past-accordion__chevron{
    transform:rotate(180deg);
  }
  /* Indented + bordered so the months inside visibly read as nested
     under "Past", not as siblings at the same level — and a smaller
     heading size than the toggle itself reinforces that hierarchy
     without touching buildMonthSection's shared markup (this just
     overrides from the outside, scoped to this one container). */
  .past-accordion__body{
    overflow:hidden;
    transition:max-height .25s ease;
    padding-left:20px;
    border-left:1px solid var(--white-hairline);
  }
  .past-accordion__body .month-head h2{
    font-size:16px;
  }

  /* Prefile/crossover: hollow outlined tags above the meter, using the
     categorical-tag color system (not semantic status colors) — each
     phase appears exactly once per card. Named .tag (not .chip) so it
     never collides with the filter chip buttons above. */
  .chip-row{
    display:flex;
    flex-wrap:wrap;
    gap:6px;
    margin:8px 0 0;
    min-height:22px;
  }
  .tag{
    display:inline-flex;
    align-items:center;
    gap:5px;
    font-family:'Satoshi',sans-serif;
    font-size:10px;
    line-height:1;
    font-weight:500;
    padding:4px 9px 3px;
    border-radius:var(--radius-full);
    background:transparent;
    white-space:nowrap;
  }
  .tag.crossover{color:var(--sky-700);border:1px solid var(--sky-600);}
  .tag.dual-bid{cursor:pointer;}
  .bid-caret{width:11px;height:11px;flex:none;transition:transform .15s ease;}
  .tag.dual-bid[aria-expanded="true"] .bid-caret{transform:rotate(180deg);}
  .bid-detail{
    display:none;
    flex-basis:100%;
    gap:14px;
    padding:8px 10px;
    background:var(--teal-50, #F0FDFA);
    border:1px solid var(--teal-600);
    border-radius:var(--radius-md);
    font-family:'Satoshi',sans-serif;
    font-size:11.5px;
    color:var(--slate-700);
  }
  .bid-detail.open{display:flex;}
  .bid-detail b{color:var(--teal-700);font-family:'Plus Jakarta Sans',sans-serif;font-weight:700;margin-right:4px;}
  .tag.bid{color:var(--teal-700);border:1px solid var(--teal-600);}
  .tag .cdot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;}

  /* year meter: a fixed Jan–Dec 2027 track. Only the portion the
     legislature is actually in session gets filled; the rest stays a
     light, low-opacity track so position-in-year is always legible. */
  .yearmeter{
    position:relative;
    height:7px;
    border-radius:var(--radius-sm);
    background:var(--slate-100);
    margin:2px 0 6px;
    overflow:hidden;
  }
  .yearmeter .fill{
    position:absolute;
    top:0;bottom:0;
    background:var(--emerald-600);
    border-radius:var(--radius-sm);
  }
  .meter-dates{
    display:flex;
    justify-content:space-between;
    font-family:'Satoshi',sans-serif;
    font-size:10.5px;
    color:var(--slate-800);
  }

  /* duration caption: visually separated from the dates above it with its
     own top border + spacing, so it reads as a distinct secondary stat
     instead of crowding the meter. */
  .days-caption{
    margin-top:auto;
    padding-top:8px;
    border-top:1px solid var(--slate-100);
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:11px;
    color:var(--slate-500);
  }
  .days-caption b{font-family:'Plus Jakarta Sans',sans-serif;color:var(--slate-700);font-weight:700;}
  .days-caption b.status-soon{color:var(--emerald-700);}
  .days-caption b.status-urgent{color:var(--amber-700);}
  .status-days{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:11px;
    margin-left:8px;
  }
  .status-days.status-soon{color:var(--emerald-700);}
  .status-days.status-urgent{color:var(--amber-700);}

  /* TABLE VIEW */
  .table-wrap{border:1px solid var(--slate-200);border-radius:var(--radius-lg);background:#fff;}

  /* TIMELINE VIEW */
  .timeline-controls{
    display:flex;
    justify-content:space-between;
    align-items:center;
    flex-wrap:wrap;
    gap:12px;
    margin-bottom:16px;
  }
  .year-toggle{display:flex;background:var(--white-faint);border:1px solid var(--white-hairline);border-radius:var(--radius-full);padding:3px;}
  .year-toggle button{
    border:none;background:transparent;padding:6px 16px;
    font-family:'Satoshi',sans-serif;font-weight:700;font-size:13px;
    color:var(--white-muted);border-radius:var(--radius-full);cursor:pointer;
  }
  .year-toggle button.active{background:var(--raspberry-500);color:#fff;}
  .timeline-sort{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
  .timeline-sort-label{
    font-family:'Satoshi',sans-serif;
    font-weight:700;
    font-size:12px;
    color:var(--white-muted);
    margin-right:2px;
  }
  .timeline-sort button{
    border:1px solid var(--white-hairline);
    background:var(--white-faint);
    padding:6px 12px;
    font-family:'Satoshi',sans-serif;
    font-weight:700;
    font-size:12px;
    color:var(--white-muted);
    border-radius:var(--radius-full);
    cursor:pointer;
  }
  .timeline-sort button.active{background:var(--ultra-600);border-color:var(--ultra-600);color:#fff;}
  .timeline-legend{display:flex;flex-wrap:wrap;gap:16px;font-family:'Satoshi',sans-serif;font-size:12px;color:var(--white-muted);}
  .timeline-legend span{display:flex;align-items:center;gap:6px;}
  .tl-swatch{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;flex:none;}
  .tl-swatch--bar{width:16px;height:6px;border-radius:2px;background:var(--emerald-600);}
  .tl-swatch--dot{width:8px;height:8px;border-radius:50%;background:var(--indigo-600);}
  .tl-swatch--bolt{background:var(--raspberry-500);color:#fff;width:13px;height:13px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;}
  .tl-swatch--bolt svg{width:60%;height:60%;}
  .tl-swatch--today{width:0;height:14px;border-left:2px dashed var(--raspberry-300);}

  .timeline-wrap{background:#fff;border:1px solid var(--slate-200);border-radius:var(--radius-lg);}
  .timeline-header{position:sticky;top:0;z-index:3;display:flex;border-bottom:1px solid var(--slate-200);background:var(--slate-50);border-radius:var(--radius-lg) var(--radius-lg) 0 0;}
  .timeline-name-col{width:140px;flex:none;padding:10px 12px;}
  .timeline-axis-col{
    flex:1;
    display:flex;
    position:relative;
    padding:10px 8px;
  }
  .timeline-axis-col span{
    flex:1;
    text-align:center;
    font-family:'Satoshi',sans-serif;
    font-weight:700;
    font-size:10.5px;
    text-transform:uppercase;
    letter-spacing:.04em;
    color:var(--slate-500);
  }
  .timeline-body{position:relative;}
  .timeline-row{display:flex;align-items:center;border-bottom:1px solid var(--slate-100);min-height:34px;}
  .timeline-row:last-child{border-bottom:none;}
  .timeline-row .timeline-name-col{
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:12.5px;
    color:var(--slate-900);
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .timeline-row .timeline-axis-col{padding:0 8px;height:34px;}
  .tl-track{
    position:absolute;
    left:8px;right:8px;top:50%;
    height:1px;
    background:var(--slate-100);
  }
  .tl-track-ticks{
    position:absolute;
    left:8px;right:8px;top:0;bottom:0;
    display:flex;
    pointer-events:none;
  }
  .tl-track-ticks div{flex:1;border-left:1px solid var(--slate-100);}
  .tl-bar{position:absolute;top:50%;transform:translateY(-50%);height:8px;border-radius:4px;overflow:hidden;background:var(--slate-200);cursor:pointer;}
  .tl-bar-fill{position:absolute;top:0;left:0;bottom:0;background:var(--emerald-600);}
  .tl-dot{
    position:absolute;top:50%;
    width:9px;height:9px;
    border-radius:50%;
    background:var(--indigo-600);
    border:2px solid #fff;
    box-shadow:0 0 0 1px var(--indigo-600);
    transform:translate(-50%,-50%);
    cursor:pointer;
  }
  .icon-badge{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    vertical-align:middle;
    flex:none;
    border-radius:50%;
    color:#fff;
  }
  .icon-badge svg{width:60%;height:60%;}
  /* Only for icon-badges sitting inline in running text (the caption's
     "Starts in 2 days"), which has no flex gap to space it automatically —
     the stat-summary usage already gets spacing from its own flex gap. */
  .icon-badge--inline{margin-right:5px;}
  .tl-bolt{
    position:absolute;top:50%;
    width:15px;height:15px;
    border-radius:50%;
    background:var(--raspberry-500);
    color:#fff;
    display:flex;align-items:center;justify-content:center;
    transform:translate(-50%,-50%);
    cursor:pointer;
  }
  .tl-bolt svg{width:9px;height:9px;}
  .tl-today-line{
    position:absolute;
    top:0;bottom:0;
    width:0;
    border-left:2px dashed var(--raspberry-500);
    z-index:5;
    pointer-events:none;
  }
  .tl-today-label{
    position:absolute;
    top:-10px;
    transform:translateX(-50%);
    background:var(--raspberry-500);
    color:#fff;
    font-family:'Plus Jakarta Sans',sans-serif;
    font-weight:700;
    font-size:9px;
    text-transform:uppercase;
    letter-spacing:.04em;
    padding:2px 6px;
    border-radius:var(--radius-sm);
    white-space:nowrap;
  }
  @media (max-width:640px){
    .timeline-name-col{width:88px;font-size:11px;}
  }
  table{width:100%;border-collapse:collapse;font-size:13.5px;}
  th,td{padding:11px 14px;text-align:left;white-space:nowrap;}
  thead th{
    position:sticky;
    top:0;
    z-index:3;
    background:#fff;
    font-family:'Satoshi',sans-serif;
    font-size:11px;
    font-weight:500;
    text-transform:uppercase;
    letter-spacing:.05em;
    color:var(--slate-500);
    border-bottom:1px solid var(--slate-100);
    cursor:pointer;
    user-select:none;
    white-space:nowrap;
  }
  thead th:hover{color:var(--ultra-600);}
  thead th.sorted{color:var(--ultra-600);}
  .sort-icon{
    display:inline-block;
    width:11px;height:11px;
    margin-left:4px;
    vertical-align:-2px;
    color:var(--slate-400);
    opacity:.7;
  }
  thead th:hover .sort-icon, thead th.sorted .sort-icon{color:var(--ultra-600);opacity:1;}
  tbody tr{border-bottom:1px solid var(--slate-100);}
  tbody tr:hover{background:var(--slate-50);}
  tbody tr:last-child{border-bottom:none;}
  td.state{font-family:'Plus Jakarta Sans',sans-serif;font-weight:700;color:var(--slate-900);}
  td.mono{font-family:'Satoshi',sans-serif;color:var(--slate-500);}
  /* Ties the table back to the card view's color language, so switching
     between By Month and By State doesn't feel like two different apps:
     indigo = prefile, sky = crossover, emerald = session (matches the
     meter fill and the Session/Prefile badges on the cards). */
  td.mono.col-prefile{color:var(--indigo-700);font-weight:500;}
  td.mono.col-crossover{color:var(--sky-700);font-weight:500;}
  td.mono.col-session{color:var(--emerald-700);font-weight:500;}
  .yes{color:var(--slate-700);font-weight:700;}
  .no{color:var(--slate-300);}

  .note{
    margin-top:40px;
    padding:16px 18px;
    background:var(--ink-900);
    border-left:3px solid var(--amber-600);
    border-radius:var(--radius-md);
    font-size:13px;
    color:var(--white-muted);
    line-height:1.6;
  }

  @media (max-width:640px){
    .hero-inner{padding:40px 16px 32px;}
    thead{display:none;}
    table, tbody, tr, td{display:block;width:100%;}
    tbody tr{padding:10px 14px;border-bottom:1px solid var(--slate-100);}
    td{padding:2px 0;white-space:normal;}
    td.state{font-size:16px;margin-bottom:4px;}
    td:before{
      content:attr(data-label);
      font-family:'Satoshi',sans-serif;
      font-size:10px;
      text-transform:uppercase;
      color:var(--slate-500);
      display:inline-block;
      width:110px;
    }
  }
