/* EmbodyList — mobile-first, responsive, light by default */
:root{
  --bg:#f7f8fa; --card:#ffffff; --ink:#1a1d24; --muted:#6b7280; --line:#e5e7eb;
  --col:860px;                 /* width of the boxed content column */
  --rule:#ccd2da;              /* the two lines down the sides */
  --brand:#2563eb; --brand-ink:#ffffff; --accent:#0ea5e9;
  --ok:#16a34a; --warn:#d97706; --bad:#dc2626;
  --pill:#eef2ff; --chipbg:#eef1f5; --chip-on:#2563eb; --chip-on-ink:#fff;
  --shadow:0 1px 3px rgba(0,0,0,.08),0 4px 16px rgba(0,0,0,.05);
  --radius:14px;
}
/* Dark is opt-in. The same variables are declared twice: once for an explicit
   choice, once for people who asked to follow the device. They cannot be
   combined into one selector list without dragging the media query over the
   explicit case too, which would break "dark on a light phone". */
:root[data-theme="dark"]{
  --bg:#10131a; --card:#181c25; --ink:#e7eaf0; --muted:#98a1b3; --line:#262b36;
  --rule:#39414f;
  --brand:#3b82f6; --pill:#1e2637; --chipbg:#222835;
  --shadow:0 1px 3px rgba(0,0,0,.4);
}
@media (prefers-color-scheme: dark){
  :root[data-theme="system"]{
    --bg:#10131a; --card:#181c25; --ink:#e7eaf0; --muted:#98a1b3; --line:#262b36;
    --rule:#39414f;
    --brand:#3b82f6; --pill:#1e2637; --chipbg:#222835;
    --shadow:0 1px 3px rgba(0,0,0,.4);
  }
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
/* Two hairlines running the full height of the window, level with the
   content column, so the list reads as a page rather than as text floating on
   a background. Fixed rather than scrolled: they should not stop at the end of
   the events. */
body::before, body::after{
  content:""; position:fixed; top:0; bottom:0; width:1px;
  background:var(--rule); z-index:40; pointer-events:none;
}
body::before{left:max(8px, calc(50% - var(--col) / 2))}
body::after{right:max(8px, calc(50% - var(--col) / 2))}

body{
  background:var(--bg); color:var(--ink);
  font:15px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,sans-serif;
  padding-bottom:42px; /* room for the bottom nav on mobile */
}
button{font:inherit; cursor:pointer}
.hidden{display:none !important}
.muted{color:var(--muted)} .small{font-size:12px}

/* header */
.top{
  position:sticky; top:0; z-index:30; background:var(--card);
  border-bottom:1px solid var(--line);
  display:flex; flex-direction:column; gap:7px; padding:7px 12px 9px;
}
/* row 1: the name, centred, deliberately shallow */
.brand{
  display:flex; align-items:center; justify-content:center; gap:6px;
  font-weight:700; font-size:16px; line-height:1.1;
}
.brand i{font-style:normal; font-weight:400; color:var(--muted)}
.logo{color:var(--brand); font-size:17px}
/* row 2: city, search and account - always a single line */
.top-controls{
  display:flex; gap:8px; width:100%; align-items:center;
  flex-wrap:nowrap; min-width:0;
}
.top-controls select,.top-controls input[type=search]{
  background:var(--bg); color:var(--ink); border:1px solid var(--line);
  border-radius:10px; padding:7px 9px; font:inherit; min-width:0;
}
.top-controls select{flex:0 1 38%; max-width:38%}
/* type-to-search city picker: the select stays in the DOM (the app reads and
   sets its value) but the visible control is the input + menu */
.citybox{position:relative; flex:0 1 38%; max-width:38%; min-width:0; display:flex; align-items:center}
.citybox select{display:none}
.citybox input{width:100%; min-width:0; background:var(--bg); color:var(--ink);
  border:1px solid var(--line); border-radius:10px; padding:7px 24px 7px 9px; font:inherit}
.citybox #cityArrow{position:absolute; right:1px; top:50%; transform:translateY(-50%);
  border:none; background:none; color:var(--muted); font-size:14px; padding:4px 7px; cursor:pointer}
.citymenu{position:absolute; left:0; top:calc(100% + 4px); z-index:40; min-width:250px;
  max-width:min(92vw,360px); max-height:60vh; overflow-y:auto; background:var(--bg);
  border:1px solid var(--line); border-radius:12px; box-shadow:0 8px 24px rgba(0,0,0,.18); padding:4px}
.citymenu.hidden{display:none}
.cm-item{display:flex; justify-content:space-between; align-items:center; gap:10px; width:100%;
  text-align:left; background:none; border:none; color:var(--ink); font:inherit; padding:8px 10px;
  border-radius:8px; cursor:pointer}
.cm-item:hover,.cm-item.focus{background:var(--chipbg)}
.cm-item.cur{font-weight:700}
.cm-item .cm-n{color:var(--muted); font-size:12px; flex:0 0 auto}
.cm-item.cm-events{position:sticky; bottom:-4px; background:var(--bg); border-top:1px solid var(--line);
  border-radius:0; margin-top:4px; padding-top:10px}
.cm-item.cm-head{color:var(--muted); cursor:default; font-size:12px}
.cm-item.cm-head:hover{background:none}
.cm-item.cm-back{color:var(--muted)}
.top-controls input[type=search]{flex:1 1 auto; min-width:0; max-width:none}
.top-controls .btn{flex:0 0 auto; padding:7px 11px; white-space:nowrap}
.btn{
  background:var(--chipbg); color:var(--ink); border:1px solid var(--line);
  border-radius:10px; padding:8px 14px;
}
.btn.primary{background:var(--brand); border-color:var(--brand); color:var(--brand-ink)}
.avatar-btn{border:none;background:none;padding:0}
.avatar-btn img{width:30px;height:30px;border-radius:50%;display:block}
.avatar-btn{flex:0 0 auto}

/* chips survive the filter bar: preferences reuses them */
.chip{
  background:var(--chipbg); border:1px solid var(--line); color:var(--ink);
  border-radius:999px; padding:6px 12px; white-space:nowrap; font-size:13px;
}
.chip.on{background:var(--chip-on); color:var(--chip-on-ink); border-color:var(--chip-on)}
.chip .dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px}
input[type=range]{accent-color:var(--brand)}

/* hamburger - preferences is now the only route to every filter, so it needs
   to look like a control rather than a hint */
.menu-btn{
  flex:0 0 auto; width:34px; height:30px; padding:0 7px; position:relative;
  display:flex; flex-direction:column; justify-content:center; gap:4px;
  background:var(--bg); border:1px solid var(--line); border-radius:8px;
}
.menu-btn span{display:block; height:2px; border-radius:2px; background:var(--ink)}
.menu-btn:hover{border-color:var(--brand)}
.menu-btn:hover span{background:var(--brand)}
/* a dot whenever something behind the menu is narrowing the list */
.menu-btn.active::after{
  content:""; position:absolute; top:-3px; right:-3px; width:8px; height:8px;
  border-radius:50%; background:var(--brand); border:1.5px solid var(--card);
}

/* list */
.list{max-width:860px; margin:0 auto; padding:8px 14px 40px}
.day-head{
  font-weight:700; margin:22px 2px 8px; font-size:16px; color:var(--ink);
  text-transform:uppercase; letter-spacing:.04em;
}
/* One event = one line, read like a spreadsheet: time, colour, name.
   Everything else lives behind a tap. */
.card{
  background:transparent; border:0; border-bottom:1px solid var(--line);
  border-radius:0; box-shadow:none; padding:7px 10px; margin:0;
  display:flex; gap:9px; align-items:flex-start; cursor:pointer;
}
.card:hover{background:var(--chipbg)}
.card:active{background:var(--chipbg)}
.card .time{
  flex:0 0 auto; min-width:58px; text-align:right;
  font-size:12.5px; font-weight:500; color:var(--muted); line-height:18px;
  font-variant-numeric:tabular-nums;
}
/* the event's own category colour, the only decoration on the row */
.card .cdot{flex:0 0 auto; width:8px; height:8px; border-radius:50%; margin-top:5px}
.card .main{flex:1; min-width:0}
/* A long name gets a second line rather than an ellipsis: the whole point of
   the list is to read the names, and a truncated one is useless. Rows are
   therefore not all the same height, which is fine - two lines is the cap. */
.card h3{
  margin:0; font-size:13px; font-weight:400; line-height:18px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}
.card .meta{font-size:12.5px; color:var(--muted); display:flex; flex-wrap:wrap; gap:4px 10px}
.pill{
  display:inline-block; background:var(--pill); border-radius:999px; padding:1px 7px;
  font-size:10.5px; font-weight:600;
}
.ver-badge{font-size:10.5px; font-weight:600; border-radius:999px; padding:1px 7px}
.ver-verified{background:rgba(22,163,74,.12); color:var(--ok)}
.ver-listed{background:rgba(14,165,233,.12); color:var(--accent)}
.ver-stale{background:rgba(217,119,6,.12); color:var(--warn)}
.ver-unverified{background:rgba(220,38,38,.10); color:var(--bad)}
.dist{color:var(--accent); font-weight:600}
.empty{color:var(--muted); text-align:center; padding:60px 20px}

/* bottom nav (mobile) */
.bottomnav{
  position:fixed; bottom:0; left:0; right:0; z-index:30;
  background:var(--card); border-top:1px solid var(--line);
  display:flex; justify-content:space-around; padding:2px 0 max(2px, env(safe-area-inset-bottom));
}
.bottomnav button{
  border:none; background:none; color:var(--muted); font-size:13px; line-height:1.4;
  display:flex; flex-direction:row; align-items:center; gap:5px; padding:2px 12px;
}
.bottomnav button span{font-size:11px}
.bottomnav button.on{color:var(--brand)}

/* modal */
.modal{
  position:fixed; inset:0; z-index:50; background:rgba(0,0,0,.45);
  display:flex; align-items:flex-end; justify-content:center;
}
.sheet{
  background:var(--card); color:var(--ink); width:100%; max-width:640px;
  border-radius:18px 18px 0 0; padding:20px 18px 26px; position:relative;
  max-height:88vh; overflow-y:auto;
}
.sheet.narrow{max-width:420px}
.close{
  position:absolute; top:10px; right:12px; border:none; background:var(--chipbg);
  border-radius:50%; width:32px; height:32px; font-size:18px; color:var(--ink);
}
/* Sits immediately left of the round close button, same vertical rhythm.
   Changes already apply as you make them - this is reassurance, not a
   gate, which is why the X saves too rather than discarding. */
.save-btn{
  position:absolute; top:10px; right:52px; height:32px; padding:0 14px;
  border:none; border-radius:16px; background:var(--brand); color:var(--brand-ink);
  font-size:13.5px; font-weight:600;
}
.save-btn.saved{background:var(--chipbg); color:var(--muted)}
.sheet h2{margin:6px 0 8px; font-size:19px; padding-right:104px}
.m-head{display:flex; gap:8px; align-items:center; margin-top:4px}
.m-row{font-size:14px; margin:4px 0; color:var(--ink)}
.m-label{font-weight:700; font-size:13px; margin:14px 0 6px}
.m-hint{font-weight:400; color:var(--muted)}
.src{
  display:flex; align-items:center; gap:8px; padding:7px 0; border-top:1px solid var(--line);
  font-size:13.5px;
}
.src:first-child{border-top:none}
.src .tier{font-size:10.5px; font-weight:700; border-radius:5px; padding:2px 6px; background:var(--pill)}
.src .tier.t1{background:rgba(22,163,74,.14); color:var(--ok)}
.src .tier.t2{background:rgba(14,165,233,.14); color:var(--accent)}
.src .tier.t5,.src .tier.t6{background:rgba(217,119,6,.12); color:var(--warn)}
.src a{color:var(--brand); text-decoration:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.m-actions{display:flex; gap:10px; margin-top:14px}
.m-actions .btn.on{background:var(--brand); color:var(--brand-ink); border-color:var(--brand)}
.m-report{display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:14px; font-size:12.5px; color:var(--muted)}
.linkbtn{border:none; background:none; color:var(--brand); font-size:12.5px; padding:2px}
.m-similar{margin-top:30px; opacity:.72}
.m-similar .m-label{font-size:10.5px; letter-spacing:.09em; text-transform:uppercase}
.m-similar .sim{
  padding:0; border-top:none; margin-top:7px;
  font-size:12px; line-height:1.4; color:var(--muted); cursor:pointer;
}
.m-similar .sim:hover{color:var(--ink)}
.m-similar .sim .when{color:var(--muted); font-size:11px}
.auth-btns{display:flex; flex-direction:column; gap:10px; margin:16px 0}
.auth-btns .btn{padding:11px; font-weight:600; text-align:center}

/* prefs */
.pref-section{margin:16px 0}
.pref-section h3{font-size:14px; margin:0 0 8px}
.int-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:6px}
.int-grid label{
  display:flex; gap:7px; align-items:center; font-size:13px;
  background:var(--chipbg); border:1px solid var(--line); border-radius:9px; padding:7px 9px;
}
.pref-row{display:flex; align-items:center; gap:10px; margin:8px 0; font-size:14px; flex-wrap:wrap}
.pref-row select,.pref-row input[type=text]{
  background:var(--bg); color:var(--ink); border:1px solid var(--line); border-radius:8px; padding:7px 9px; font:inherit;
}
.suggest-box{display:flex; gap:8px; margin-top:6px}
.suggest-box input{flex:1}

.toast{
  position:fixed; bottom:80px; left:50%; transform:translateX(-50%);
  background:var(--ink); color:var(--bg); border-radius:10px; padding:10px 18px;
  font-size:14px; z-index:60; box-shadow:var(--shadow); max-width:88vw; text-align:center;
}

/* ---- tablet & desktop ---- */
@media (min-width:700px){
  body{padding-bottom:0}
  .bottomnav{
    position:sticky; top:0; bottom:auto; border-top:none;
    display:inline-flex; background:none; border:none;
  }
  /* desktop: nav moves into header area via order tweak */
  .top{padding:12px 22px}
  .list{padding:8px 22px 60px}
  .modal{align-items:center}
  .sheet{border-radius:18px; max-height:84vh}
  .card .time{min-width:78px}
  .bottomnav{
    position:fixed; top:auto; bottom:18px; left:auto; right:18px; width:auto;
    background:var(--card); border:1px solid var(--line); border-radius:14px;
    box-shadow:var(--shadow); padding:4px 6px;
  }
  .bottomnav button{padding:3px 12px; gap:6px; font-size:13px}
  .bottomnav button span{font-size:12px}
}
@media (min-width:1100px){
  :root{--col:960px}
  .list{max-width:960px}
}

/* --- unscheduled (no-date) cards, behind the "No-date events" toggle --- */
.card.unsched{opacity:.85}
.card.unsched .time{color:var(--muted); font-style:italic}
.unsched-text{font-size:14.5px; line-height:1.45}
.unsched-link{display:inline-block; margin-top:4px; font-size:13px}

/* ---------- install-as-an-app banner ---------- */
/* Sits above everything, points at the browser's own menu button (top right on
   Chrome/Android, which is where "Install and create shortcut" lives). */
.install-banner{
  position:relative;
  display:flex; align-items:flex-start; gap:12px;
  padding:14px 46px 15px 16px;
  background:#2F5D4E; color:#F4F7F1;
  font-size:14px; line-height:1.45;
}
.install-banner.hidden{display:none}
.install-arrow{
  position:absolute; top:10px; right:78px;
  width:62px; height:44px; color:#E9A45C; overflow:visible;
  pointer-events:none;
  animation:install-nudge 1.9s ease-in-out infinite;
}
@keyframes install-nudge{
  0%,100%{transform:translate(0,0)}
  50%{transform:translate(3px,-4px)}
}
@media (prefers-reduced-motion: reduce){
  .install-arrow{animation:none}
}
.install-copy{flex:1 1 auto; min-width:0; padding-right:70px}
.install-copy strong{display:block; font-weight:600}
.install-copy span{display:block; color:#CFDCD2}
.install-copy b{color:#F4F7F1; font-weight:600}
.install-btn{
  flex:0 0 auto; align-self:center;
  background:#E9A45C; color:#1A2620; border:0; border-radius:8px;
  padding:8px 14px; font:inherit; font-weight:600; cursor:pointer;
}
.install-btn.hidden{display:none}
.install-x{
  display:inline-flex; align-items:center; gap:7px; margin-top:9px;
  background:transparent; border:1px solid rgba(255,255,255,.3); color:#CFDCD2;
  font:inherit; font-size:12.5px; line-height:1;
  padding:6px 11px; cursor:pointer; border-radius:8px;
}
.install-x i{font-style:normal; font-size:15px; line-height:1}
.install-x:hover{color:#fff; background:rgba(255,255,255,.12)}
/* narrow screens: tighten the arrow and let the copy use the full width. The
   Install button stays - phones are exactly where one-tap install matters. */
@media (max-width:520px){
  .install-arrow{right:62px; width:46px; height:32px}
  .install-copy{padding-right:84px}
  .install-banner{flex-wrap:wrap}
  .install-btn{margin-top:8px; align-self:flex-start}
}

/* ---------- highlight swatches + hide controls (event detail) ---------- */
.m-hl{display:flex; align-items:center; gap:8px; margin-top:14px; flex-wrap:wrap}
.m-hl .m-label{margin:0}
.hl-dot{
  width:26px; height:26px; border-radius:50%; border:1px solid var(--line);
  cursor:pointer; padding:0; transition:transform .08s ease;
}
.hl-dot:hover{transform:scale(1.15)}
.hl-dot.active{outline:2px solid var(--brand); outline-offset:2px}
.hl-none{background:var(--card); color:var(--muted); font-size:15px; line-height:1}
.hl-none:hover{color:var(--warn)}
.m-hide{display:flex; gap:14px; margin-top:12px; flex-wrap:wrap}
.m-hide .linkbtn{color:var(--muted)}
.m-hide .linkbtn:hover{color:var(--warn)}
/* a highlighted row keeps its colour readable in both themes */
.card.hl h3,.card.hl .time{color:#1a1a1a}

/* --- preferences: now the single home for every filter --- */
.pref-head{display:flex; align-items:center; justify-content:space-between; gap:10px}
.pref-head h3{margin:0}
.pref-bulk{display:flex; gap:6px; flex:0 0 auto}
.pref-bulk .chip{padding:4px 10px; font-size:12px}
.pref-check{display:flex; align-items:flex-start; gap:8px; padding:5px 0}
.pref-check i{font-style:normal; display:block}
.suggest-box + .suggest-box{margin-top:7px}
