/* Public Discover pages: the layout every style shares.
   Loaded after style.css and before exactly one theme-<style>.css.

   Contract with the theme files:
   - Every colour, radius, shadow and font here is a token. The defaults below
     are neutral (they follow style.css's own tokens) so a page with no theme
     file still reads; a theme redefines them on html[data-discover-style="x"],
     which (0,1,1) out-ranks style.css's :root / [data-theme] blocks (0,1,0).
   - No containers by default: rows, chips and buttons take --row-bg,
     --radius and --shadow, which default to transparent / 0 / none. A card
     look exists only if a theme turns it on.
   - Media queries here decide WIDTH and motion only. Light/dark is the theme
     file's job and is keyed on [data-theme], never on a bare
     prefers-color-scheme query (see CLAUDE.md, the style.css section).
   Breakpoints: phone < 768 (designed at 375), tablet 768-1199, desktop >= 1200. */

html {
  --ground: var(--bg);
  --ground-2: var(--bg-soft);
  --ink: var(--text);
  --ink-dim: var(--text-muted);
  --accent-ink: var(--accent-text);
  --link-ink: var(--accent);
  --rule: var(--border);
  --focus: var(--link);
  --radius: 0;
  --shadow: none;
  --row-bg: transparent;
  --font-display: 'Noto Sans TC', 'PingFang TC', 'Heiti TC', 'Microsoft JhengHei', sans-serif;
  --font-body: 'Noto Sans TC', 'PingFang TC', 'Heiti TC', 'Microsoft JhengHei', sans-serif;
  --font-mono: ui-monospace, Menlo, Consolas, 'Noto Sans TC', monospace;
  --gutter: 16px;
}

body.disc {
  background: var(--ground); color: var(--ink);
  font-family: var(--font-body); font-size: 16px; line-height: 1.6;
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
}
.disc :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.disc h1, .disc h2, .disc h3 { font-family: var(--font-display); color: var(--ink); }

/* visually hidden, still read aloud */
.vh {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

.pub { width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 var(--gutter) 24px; }

/* ------------------------------------------------------------------ top bar */
.topbar {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 48px; margin: 0 calc(-1 * var(--gutter));
  padding: 2px calc(var(--gutter) - 4px) 2px var(--gutter);
  border-bottom: 1px solid var(--rule);
}
.brand {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; min-width: 0;
  color: var(--ink); text-decoration: none; font-family: var(--font-display);
  font-weight: 600; font-size: 1rem;
}
.brand-pin { width: 18px; height: 18px; flex: none; color: var(--accent); }
.brand-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-end { display: flex; align-items: center; gap: 2px; flex: none; }
.topbar-login {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px;
  color: var(--ink); text-decoration: none; font-size: .9rem;
}

/* ------------------------------------------------------------------ picker */
.style-pick > summary {
  list-style: none; width: 44px; height: 44px; display: grid; place-items: center;
  cursor: pointer; border-radius: var(--radius); color: var(--ink);
}
.style-pick > summary::-webkit-details-marker { display: none; }
.style-pick[open] > summary { background: var(--ground-2); }
.dots { display: inline-flex; gap: 3px; }
.dots i { width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--rule); }
.dots i:nth-child(1) { background: var(--accent); }
.dots i:nth-child(2) { background: var(--ink); }
.dots i:nth-child(3) { background: var(--ground-2); }
.style-panel {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 40;
  padding: 12px var(--gutter) 16px; background: var(--ground-2);
  border-bottom: 1px solid var(--rule); box-shadow: var(--shadow);
}
.sw-form { margin: 0; }
.sw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.sw-btn {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 48px; padding: 6px 10px;
  font: inherit; font-size: .9rem; text-align: start; color: var(--ink); cursor: pointer;
  background: var(--row-bg); border: 1px solid var(--rule); border-radius: var(--radius);
}
.sw-btn[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.sw-name { flex: 1; min-width: 0; }
.sw-cur { display: inline-flex; color: var(--accent); }
.sw-btn:not([aria-pressed="true"]) .sw-cur { display: none; }
.sw-check { width: 16px; height: 16px; }
/* Each swatch previews its own style, not the active one, so the colours
   are fixed here rather than read from the loaded theme file. */
.swatch { display: inline-flex; flex: none; width: 36px; height: 24px; border: 1px solid rgba(128, 128, 128, .45); }
.swatch i { flex: 1; background: var(--sw); }
[data-swatch="midnight"]   { --sw-1: #101114; --sw-2: #C9A66B; --sw-3: #2E2438; }
[data-swatch="newspaper"]  { --sw-1: #EEE9DE; --sw-2: #202020; --sw-3: #2C4F66; }
[data-swatch="wayfinding"] { --sw-1: #E7E5DF; --sw-2: #2364B1; --sw-3: #E37536; }
[data-swatch="market"]     { --sw-1: #FFF3DE; --sw-2: #C94B32; --sw-3: #6D8759; }
[data-swatch="neon"]       { --sw-1: #080A0F; --sw-2: #35E0D0; --sw-3: #FF3CAC; }
/* --sw-1 is the page ground, and grounds collide in pairs (midnight/neon are
   both near-black, newspaper/wayfinding/market all pale), so it goes last:
   the first two bands are the two colours no other style shares. */
.swatch i:nth-child(1) { --sw: var(--sw-2); }
.swatch i:nth-child(2) { --sw: var(--sw-3); }
.swatch i:nth-child(3) { --sw: var(--sw-1); }

.style-foot { margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--rule); }
.style-foot h2 { margin: 0 0 12px; font-size: 1.05rem; font-weight: 600; }

/* ------------------------------------------------------------------ masthead */
.masthead { padding: 20px 0 12px; }
.kicker { margin: 0 0 6px; font-size: .8rem; letter-spacing: .06em; color: var(--ink-dim); }
.masthead h1 {
  margin: 0 0 8px; font-size: clamp(1.7rem, 1.2rem + 2.4vw, 3rem); line-height: 1.14;
  font-weight: 600; letter-spacing: -.01em;
}
.lede { margin: 0; color: var(--ink-dim); max-width: 56ch; }
.entry { display: none; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 20px; }
.mh-side { display: none; }
.ticker { list-style: none; margin: 0; padding: 0; }
.ticker .dup { display: none; }
.ticker-lead { margin: 0 0 6px; font-size: .8rem; color: var(--ink-dim); }

/* ------------------------------------------------------------------ buttons */
.cta, .cta-quiet, .save, .maps-trigger.is-primary {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 20px; font: inherit; font-size: .95rem; line-height: 1.2;
  text-decoration: none; cursor: pointer; border-radius: var(--radius); box-shadow: var(--shadow);
}
.cta-quiet, .save { background: var(--row-bg); color: var(--ink); border: 1px solid var(--rule); }
.cta, .is-primary { background: var(--accent); color: var(--accent-ink); border: 1px solid var(--accent); font-weight: 600; }
.maps-trigger.is-icon {
  appearance: none; width: 44px; height: 44px; padding: 0; display: grid; place-items: center;
  background: transparent; border: 0; border-radius: var(--radius); color: var(--ink-dim); cursor: pointer;
}
.maps-trigger.is-icon svg { width: 22px; height: 22px; }
.maps-trigger.is-icon:hover { color: var(--link-ink); }

/* ------------------------------------------------------------------ chips */
.dirs { margin: 4px calc(-1 * var(--gutter)) 8px; }
.chips {
  display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 2px var(--gutter);
  overflow-x: auto; scroll-snap-type: x proximity; overscroll-behavior-x: contain;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  /* Snap to the gutter, not to x=0: without it an overflowing row (the
     districts, at 375) opens scrolled by the gutter, first chip flush on the
     screen edge. Every style needs it, so it lives here, not per theme. */
  scroll-padding-inline: var(--gutter);
}
.chips::-webkit-scrollbar { display: none; }
.chips .lbl { flex: none; font-size: .8rem; color: var(--ink-dim); }
.chip {
  flex: none; scroll-snap-align: start; display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 12px; white-space: nowrap; font-size: .88rem; text-decoration: none;
  color: var(--ink); background: var(--row-bg); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.chip .n { font-size: .78rem; color: var(--ink-dim); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ feed */
.feed { margin-top: 12px; counter-reset: v; }
.sec-head { display: flex; align-items: baseline; gap: 10px; padding: 8px 0; }
.sec-head h2 { margin: 0; font-size: 1.15rem; font-weight: 600; }
.sec-head .n { font-size: .85rem; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.venues { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.venue {
  display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; column-gap: 12px;
  padding: 12px 0; background: var(--row-bg); border-radius: var(--radius); box-shadow: var(--shadow);
}
.venue + .venue { border-top: 1px solid var(--rule); }
.venue > .maps-trigger { grid-column: -2; }
.venue-name { margin: 0; font-size: 1.05rem; line-height: 1.35; font-weight: 600; }
.venue-name a { color: var(--ink); text-decoration: none; }
.venue-name a:hover { color: var(--link-ink); }
.venue .meta { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 3px; font-size: .8rem; color: var(--ink-dim); }
.venue .addr {
  margin: 2px 0 0; font-size: .82rem; color: var(--ink-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cta-band {
  display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0; padding: 16px 0;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.cta-band > a { flex: 1 1 140px; }
.empty { padding: 24px 0; color: var(--ink-dim); }

/* ------------------------------------------------------------------ list + venue */
.crumb {
  display: flex; align-items: center; gap: 6px; min-height: 44px; margin-top: 4px;
  overflow-x: auto; white-space: nowrap; scrollbar-width: none;
  font-size: .84rem; color: var(--ink-dim);
}
.crumb::-webkit-scrollbar { display: none; }
.crumb a {
  display: inline-flex; align-items: center; min-height: 44px; color: var(--ink);
  text-decoration: underline; text-decoration-color: var(--rule); text-underline-offset: 3px;
}
.list-head { padding: 4px 0 12px; }
.list-head h1, .v-head h1 {
  margin: 0 0 8px; font-size: clamp(1.5rem, 1.1rem + 2vw, 2.6rem); line-height: 1.2; font-weight: 600;
}

.v-head { padding-top: 4px; }
.facts { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; padding: 0; }
.facts li > * {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; font-size: .84rem;
  color: var(--ink); text-decoration: none; background: var(--row-bg);
  border: 1px solid var(--rule); border-radius: var(--radius);
}
.v-addr { margin: 0 0 4px; color: var(--ink-dim); }
.v-links { margin: 0; }
.ext { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--link-ink); }
.ext svg { width: 14px; height: 14px; }
.actions { display: flex; gap: 10px; margin: 16px 0; }
.actions > * { flex: 1 1 0; min-height: 48px; }
.intro { margin: 20px 0; line-height: 1.75; max-width: 64ch; }
.howto { margin: 24px 0 0; color: var(--ink-dim); font-size: .92rem; max-width: 64ch; }
.nearby-sec h2, .posts-sec h2 { margin: 32px 0 4px; font-size: 1.1rem; font-weight: 600; }
.nearby, .posts { list-style: none; margin: 0; padding: 0; }
.nearby li { padding: 10px 0; border-top: 1px solid var(--rule); }
.nm { color: var(--ink); font-weight: 600; text-decoration: none; }
.nm:hover { color: var(--link-ink); }
.naddr { margin: 2px 0 0; font-size: .82rem; color: var(--ink-dim); }
.nmeta { margin: 2px 0 0; font-size: .78rem; color: var(--ink-dim); }
.posts li { border-top: 1px solid var(--rule); }
.posts a {
  display: flex; align-items: center; min-height: 44px; word-break: break-all;
  font-family: var(--font-mono); font-size: .82rem; color: var(--ink-dim); text-decoration: none;
}
.posts a:hover { color: var(--link-ink); }

/* ------------------------------------------------------------------ footer */
.disc-foot {
  margin-top: 32px; padding: 12px 0 calc(16px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule);
}
.foot-links { display: flex; flex-wrap: wrap; gap: 0 20px; }
.foot-links a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--ink-dim); text-decoration: none; font-size: .86rem;
}
.foot-links a:hover { color: var(--ink); }

/* ------------------------------------------------------------------ phone only */
@media (max-width: 767.98px) {
  .masthead .lede, .list-head .lede {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  }
  .chips .lbl {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  /* The venue page's two actions sit on the bottom edge, where a thumb is,
     with the home-indicator inset reserved; .pub reserves the bar's height so
     the footer never ends up underneath it. */
  .disc--venue .actions {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; margin: 0;
    padding: 10px calc(16px + env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom))
             calc(16px + env(safe-area-inset-left));
    background: var(--ground); border-top: 1px solid var(--rule);
  }
  .disc--venue .pub { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
}

/* ------------------------------------------------------------------ tablet+ */
@media (min-width: 768px) {
  html { --gutter: 32px; }
  .pub { max-width: 784px; }
  .entry { display: flex; }
  .disc--index .cta-band { display: none; }
  .dirs { margin: 8px 0 12px; }
  .chips { flex-wrap: wrap; overflow: visible; padding: 2px 0; }
  .actions > * { flex: 0 1 auto; }
  .masthead { padding: 32px 0 16px; }
}

/* ------------------------------------------------------------------ desktop */
@media (min-width: 1200px) {
  html { --gutter: 48px; }
  .disc--index .pub, .disc--venue .pub { max-width: 1176px; }
  .disc--list .pub { max-width: 816px; }
  .masthead {
    display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 48px; align-items: end;
    padding: 48px 0 24px;
  }
  .mh-side { display: block; }
  /* Two columns, DOM order unchanged: the head, prose and posts on the left,
     the actions and the next places to try on the right. The last row is
     flexible so the right column grows into it instead of opening gaps
     between the left-hand blocks.

     The right column is the sticky aside. A grid item only sticks inside its
     own grid area, and .actions and .nearby-sec are not adjacent in the DOM
     (the intro sits between them), so they cannot share one wrapper. Each
     spans every row instead and sticks on its own: .actions gets a fixed
     height (--side-act-h) and .nearby-sec is pushed down and pinned by that
     same amount, so the two stack like one panel. A nearby list taller than
     the window scrolls inside itself rather than running off the bottom. */
  .vp {
    --side-act-h: 128px;
    display: grid; grid-template-columns: minmax(0, 1fr) 300px; column-gap: 56px;
    grid-template-rows: auto auto auto auto 1fr; align-items: start;
  }
  .v-head { grid-column: 1; grid-row: 1; }
  .intro { grid-column: 1; grid-row: 2; }
  .posts-sec { grid-column: 1; grid-row: 3; }
  .howto { grid-column: 1; grid-row: 4; }
  .vp > .actions {
    grid-column: 2; grid-row: 1 / -1; flex-direction: column; margin-top: 12px;
    position: sticky; top: 16px; height: var(--side-act-h);
  }
  .vp > .actions > * { flex: none; width: 100%; }
  .vp > .actions.is-single, .vp > .actions.is-single ~ .nearby-sec { --side-act-h: 68px; }
  .nearby-sec {
    grid-column: 2; grid-row: 1 / -1; margin-top: calc(12px + var(--side-act-h));
    position: sticky; top: calc(16px + var(--side-act-h));
    max-height: calc(100vh - 32px - var(--side-act-h)); overflow-y: auto; overscroll-behavior: contain;
  }
  .nearby-sec h2 { margin-top: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .disc *, .disc *::before, .disc *::after { animation: none !important; transition: none !important; }
}
