/* The app shell's styles. Every colour, font, corner and size is a variable. The config
   tool writes the app's design profile into index.html (<style id="app-theme">, after this
   file) as -l (light) and -d (dark) sources; this file picks the right one for the mode.
   The fallbacks below are the original look, so a page without a profile still looks as
   it always did. Parts use the component classes at the bottom (card, btn, input, list, ...)
   and the colour variables, and may add their own part.css. */

:root {
  color-scheme: light dark;
  /* light mode: the profile's -l sources, else the original look */
  --accent: var(--accent-l, #2563eb);
  --on-accent: var(--on-accent-l, #ffffff);
  --bg-light: #f6f7fb;
  --bg-dark: #0f1115;
  --bg: var(--bg-l, var(--bg-light));
  --surface: var(--surface-l, #ffffff);
  --surface-2: var(--surface-2-l, #eef0f5);
  --text: var(--text-l, #15171c);
  --muted: var(--muted-l, #5f6670);
  --line: var(--line-l, #e2e5eb);
  --field-line: var(--field-line-l, var(--line));
  --edge: var(--edge-l, var(--line));
  --btn: var(--btn-l, var(--accent));
  --on-btn: var(--on-btn-l, var(--on-accent));
  --bar-bg: var(--bar-bg-l, var(--accent));
  --bar-ink: var(--bar-ink-l, var(--on-accent));
  --bar-btn: var(--bar-btn-l, color-mix(in srgb, var(--bar-ink) 18%, transparent));
  --tabbar-bg: var(--tabbar-bg-l, var(--surface));
  --support: var(--support-l, var(--accent));
  --support-soft: var(--support-soft-l, var(--surface-2));
  --danger: var(--danger-l, #c62828);
  --on-danger: var(--on-danger-l, #ffffff);
  --ok: var(--ok-l, #2e7d32);
  --shadow: var(--shadow-l, 0 1px 2px rgba(16, 24, 40, .06), 0 6px 20px rgba(16, 24, 40, .06));
  --accent-soft: color-mix(in srgb, var(--accent) var(--soft-pct, 14%), transparent);

  /* shape, type and density (the profile layer overrides any of these) */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-head: var(--font);
  --font-display: var(--font-head);
  --font-label: var(--font);
  --label-fs: 11px;
  --label-spacing: .12em;
  --fs: 17px;
  --lh: 1.45;
  --head-weight: 700;
  --head-weight-2: 650;
  --head-case: none;
  --head-spacing: -.02em;
  --radius: 14px;
  --radius-btn: 12px;
  --radius-input: 12px;
  --radius-sheet: 20px;
  --icon-radius: 9px;
  --card-pad: 16px;
  --card-border-w: 0px;
  --card-shadow: var(--shadow);
  --btn-weight: 600;
  --btn-case: none;
  --btn-spacing: 0;
  --btn-fs: 16px;
  --btn-border-w: 0px;
  --field-border-w: 1px;
  --appbar-title-fs: 19px;
  --appbar-title-weight: 650;
  --appbar-title-case: none;
  --appbar-title-spacing: -.01em;
  --bar-rule-w: 0px;
  --bar-rule: var(--line);
  --tab-fs: 11.5px;
  --tab-weight: 600;
  --tab-ico-radius: 15px;
  --tab-on-bg: var(--accent-soft);
  --tab-on-ink: var(--accent);
  --tab-ind: transparent;
  --tab-ind-h: 0px;

  --tap: 48px;
  --appbar: 56px;
  --tabbar: 60px;
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --gutter: 16px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --accent: var(--accent-d, #2563eb);
    --on-accent: var(--on-accent-d, #ffffff);
    --bg: var(--bg-d, var(--bg-dark));
    --surface: var(--surface-d, #1a1d24);
    --surface-2: var(--surface-2-d, #252934);
    --text: var(--text-d, #eef0f4);
    --muted: var(--muted-d, #9aa3b2);
    --line: var(--line-d, #2b303a);
    --field-line: var(--field-line-d, var(--line));
    --edge: var(--edge-d, var(--line));
    --btn: var(--btn-d, var(--accent));
    --on-btn: var(--on-btn-d, var(--on-accent));
    --bar-bg: var(--bar-bg-d, var(--accent));
    --bar-ink: var(--bar-ink-d, var(--on-accent));
    --bar-btn: var(--bar-btn-d, color-mix(in srgb, var(--bar-ink) 18%, transparent));
    --tabbar-bg: var(--tabbar-bg-d, var(--surface));
    --support: var(--support-d, var(--accent));
    --support-soft: var(--support-soft-d, var(--surface-2));
    --danger: var(--danger-d, #c62828);
    --on-danger: var(--on-danger-d, #ffffff);
    --ok: var(--ok-d, #2e7d32);
    --shadow: var(--shadow-d, 0 1px 2px rgba(0, 0, 0, .3), 0 6px 20px rgba(0, 0, 0, .25));
  }
}
:root[data-theme="dark"] {
  --accent: var(--accent-d, #2563eb);
  --on-accent: var(--on-accent-d, #ffffff);
  --bg: var(--bg-d, var(--bg-dark));
  --surface: var(--surface-d, #1a1d24);
  --surface-2: var(--surface-2-d, #252934);
  --text: var(--text-d, #eef0f4);
  --muted: var(--muted-d, #9aa3b2);
  --line: var(--line-d, #2b303a);
  --field-line: var(--field-line-d, var(--line));
  --edge: var(--edge-d, var(--line));
  --btn: var(--btn-d, var(--accent));
  --on-btn: var(--on-btn-d, var(--on-accent));
  --bar-bg: var(--bar-bg-d, var(--accent));
  --bar-ink: var(--bar-ink-d, var(--on-accent));
  --bar-btn: var(--bar-btn-d, color-mix(in srgb, var(--bar-ink) 18%, transparent));
  --tabbar-bg: var(--tabbar-bg-d, var(--surface));
  --support: var(--support-d, var(--accent));
  --support-soft: var(--support-soft-d, var(--surface-2));
  --danger: var(--danger-d, #c62828);
  --on-danger: var(--on-danger-d, #ffffff);
  --ok: var(--ok-d, #2e7d32);
  --shadow: var(--shadow-d, 0 1px 2px rgba(0, 0, 0, .3), 0 6px 20px rgba(0, 0, 0, .25));
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs);
  line-height: var(--lh);
  font-family: var(--font);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
  touch-action: manipulation;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; cursor: pointer; }
a { color: var(--accent); }
img { max-width: 100%; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
svg.ico { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* ---- the frame: app bar, screens, tab bar */
#app {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background: var(--bg);
}
.boot {
  flex: 1; display: grid; place-items: center;
}
.boot-icon { width: 72px; height: 72px; border-radius: 18px; animation: boot-pulse 1.2s ease-in-out infinite; }
@keyframes boot-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

.appbar {
  flex: none;
  display: flex; align-items: center; gap: 12px;
  min-height: calc(var(--appbar) + var(--sat));
  padding: var(--sat) max(var(--gutter), var(--sar)) 0 max(var(--gutter), var(--sal));
  background: var(--bar-bg);
  color: var(--bar-ink);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .08);
  border-bottom: var(--bar-rule-w) solid var(--bar-rule);
  z-index: 2;
}
.appbar-icon { width: 32px; height: 32px; border-radius: var(--icon-radius); flex: none; }
/* The ONE Back control (CHTC7, C2): it replaces the app icon while there is somewhere to go
   back to, and its label says where (capped, ellipsised, dropped on the narrowest phones). */
.appbar-back {
  display: inline-flex; align-items: center; gap: 2px; flex: none;
  min-width: 44px; min-height: 44px; max-width: 34%;
  margin-left: -8px; padding: 0 10px 0 4px;
  border: 0; border-radius: 999px; background: transparent; color: inherit;
  font-family: var(--font); font-size: 16px; font-weight: 600; letter-spacing: 0; text-transform: none;
}
.appbar-back:active { background: var(--bar-btn); }
.appbar-back svg.ico { width: 26px; height: 26px; stroke-width: 2.4; }
.appbar-back-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.appbar.has-back .appbar-icon { display: none; }
@media (max-width: 340px) { .appbar-back-label { display: none; } .appbar-back { padding-right: 4px; } }
.appbar-title {
  flex: 1; min-width: 0;
  font-size: var(--appbar-title-fs); font-weight: var(--appbar-title-weight); letter-spacing: var(--appbar-title-spacing);
  text-transform: var(--appbar-title-case);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.appbar-actions { display: flex; align-items: center; gap: 6px; flex: none; }
.appbar-btn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 14px;
  border: 0; border-radius: 999px;
  background: var(--bar-btn);
  color: inherit; font-weight: 600; font-size: 15px;
}
.appbar-btn:active { filter: brightness(.9); }
.appbar-btn.icon-only { width: 40px; padding: 0; justify-content: center; }
/* Phones: app-bar buttons drop their text labels (tagged .appbar-btn-label) and keep the
   icon, so the title never truncates. Never hide every span: the login avatar is a span. */
@media (max-width: 480px) {
  .appbar-btn .appbar-btn-label { display: none; }
  .appbar-btn { min-width: 40px; padding: 0 10px; justify-content: center; }
}

.screens { flex: 1; min-height: 0; position: relative; }
.screen {
  position: absolute; inset: 0;
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: var(--gutter) max(var(--gutter), var(--sar)) 28px max(var(--gutter), var(--sal));
}
.screen-inner { max-width: 720px; margin: 0 auto; }
.screen.fill { overflow: hidden; padding: 0; display: flex; flex-direction: column; }
.screen.fill > .screen-inner { max-width: none; margin: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.screen-error { text-align: center; padding: 40px 16px; color: var(--muted); }

.tabbar {
  flex: none;
  display: flex; align-items: stretch;
  min-height: calc(var(--tabbar) + var(--sab));
  padding: 0 max(0px, var(--sar)) var(--sab) max(0px, var(--sal));
  background: var(--tabbar-bg);
  border-top: 1px solid var(--line);
  z-index: 2;
}
.tab {
  position: relative;
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: var(--tap);
  padding: 6px 4px 4px;
  border: 0; background: none;
  color: var(--muted); font-size: var(--tab-fs); font-weight: var(--tab-weight); letter-spacing: .01em;
  user-select: none; -webkit-user-select: none;
  transition: color .15s;
}
.tab .tab-ico {
  width: 56px; height: 30px; border-radius: var(--tab-ico-radius);
  display: grid; place-items: center;
  transition: background .15s;
  font-size: 20px; line-height: 1;
}
.tab .tab-label { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tab[aria-selected="true"] { color: var(--accent); }
.tab[aria-selected="true"] .tab-ico { background: var(--tab-on-bg); color: var(--tab-on-ink); }
.tab[aria-selected="true"]::before {
  content: ""; position: absolute; top: 0; left: 22%; right: 22%;
  height: var(--tab-ind-h); border-radius: 0 0 3px 3px; background: var(--tab-ind);
}
.tab:active .tab-ico { background: var(--surface-2); }
.tabbar.single { display: none; }

/* ---- status bits */
.offline-banner {
  position: absolute; left: 0; right: 0; top: 0;
  z-index: 3;
  text-align: center; font-size: 13px; font-weight: 600;
  padding: 6px 12px;
  background: #b45309; color: #fff;
}
/* The install card: one line over the top of the screens, existing colours only. */
.install-card {
  position: absolute; left: 10px; right: 10px; top: 10px;
  z-index: 3;
  display: flex; align-items: center; gap: 4px;
  padding: 8px 6px 8px 12px;
  background: var(--surface); color: var(--text);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  box-shadow: var(--shadow);
  font-size: 14px;
}
.install-card-text { flex: 1; min-width: 0; font-weight: 600; }
.install-card-go {
  border: 0; background: transparent; color: var(--accent);
  font-weight: 700; font-size: 14px; padding: 8px 10px; border-radius: 8px; flex: none;
}
.install-card-go:active { background: var(--accent-soft); }
.install-card-x {
  width: 36px; height: 36px; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
  display: inline-grid; place-items: center; flex: none;
}
.install-card-x:active { background: var(--surface-2); }
.install-card-x svg.ico { width: 18px; height: 18px; }
.toast-root {
  position: fixed; left: 0; right: 0;
  bottom: calc(var(--tabbar) + var(--sab) + 12px);
  display: flex; justify-content: center;
  pointer-events: none; z-index: 20;
}
.toast {
  max-width: min(92vw, 420px);
  padding: 12px 18px; border-radius: 12px;
  background: #23262e; color: #fff; font-size: 15px; font-weight: 500;
  box-shadow: var(--shadow);
  opacity: 0; transform: translateY(8px);
  transition: opacity .2s, transform .2s;
}
.toast.show { opacity: 1; transform: none; }
.toast.error { background: var(--danger); color: var(--on-danger); }
.toast.ok { background: var(--ok); }

/* ---- bottom sheet: the pop-up standard (CHTC7, C1). One sheet for every pop-up: a grip to
   swipe it down, an X that never scrolls away, a body that is the ONLY scroller (capped at
   --sheet-max), and a footer pinned outside the scroller that carries the home-bar inset.
   DOM (app.js sheet()): .sheet-backdrop (modal only), then .sheet > .sheet-grip > .sheet-handle,
   .sheet-x, .sheet-head > .sheet-title (with a title), .sheet-body, .sheet-foot[hidden]
   (> .sheet-ask while the guard asks). States: show, dragging, no-foot, modeless. */
:root { --sheet-max: 88dvh; }
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(0, 0, 0, .35);
  opacity: 0; transition: opacity .2s;
}
.sheet-backdrop.show { opacity: 1; }
.sheet-backdrop.dragging { transition: none; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 31;
  max-width: 560px; margin: 0 auto;
  display: flex; flex-direction: column;
  max-height: 88vh;
  background: var(--surface); color: var(--text);
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  padding: 0;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .18);
  transform: translateY(100%); transition: transform .25s cubic-bezier(.2, .8, .2, 1);
}
/* var() with dvh must not replace the vh line where dvh is unknown (an invalid var() would
   leave NO max-height), hence the @supports */
@supports (height: 1dvh) { .sheet { max-height: var(--sheet-max); } }
.sheet.show { transform: none; }
.sheet.dragging { transition: none; }
/* A modeless sheet (the map's pin card) lies UNDER every modal sheet's backdrop (30), so a modal
   opened while it is up dims it and blocks it; under toasts (20), so a message is never hidden
   behind it; and under a part's full-screen page (the owner page, 15). Still over the tab bar,
   the app bar and the floating buttons (2 to 5). */
.sheet.modeless { z-index: 14; box-shadow: 0 -6px 24px rgba(0, 0, 0, .24); }
.sheet-grip {
  flex: none; height: 22px; padding-top: 8px;
  display: flex; justify-content: center;
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.sheet-handle {
  width: 36px; height: 5px; border-radius: 3px; margin: 0;
  background: color-mix(in srgb, var(--muted) 45%, transparent);
}
.sheet-x {
  position: absolute; top: 2px; right: max(4px, var(--sar)); z-index: 2;
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
  background: var(--surface-2); color: var(--text);
  display: grid; place-items: center;
}
.sheet-x:active { filter: brightness(.92); }
.sheet-x svg.ico { width: 20px; height: 20px; }
.sheet-head { flex: none; padding: 2px 56px 8px max(var(--gutter), var(--sal)); touch-action: none; }
.sheet .sheet-title { margin: 0; }
.sheet-body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: none;
  padding: 4px max(var(--gutter), var(--sar)) var(--gutter) max(var(--gutter), var(--sal));
}
/* The body-at-top rule: while the body is scrolled to its top, a downward finger drag is the
   sheet's (swipe to close), never a browser pan. pan-down = only scrolls that START by moving
   the content down (a finger moving UP) are the browser's; a browser that ignores the
   directional value keeps the default and app.js cancels the first downward touchmove. */
.sheet-body.at-top { touch-action: pan-down pinch-zoom; }
.sheet.no-foot .sheet-body { padding-bottom: calc(var(--gutter) + var(--sab)); }
/* a legacy sheet's first heading keeps clear of the X */
.sheet-body > h2:first-child, .sheet-body > form:first-child > h2:first-child { margin-right: 44px; }
.sheet-foot {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 10px max(var(--gutter), var(--sar)) calc(10px + var(--sab)) max(var(--gutter), var(--sal));
  background: var(--surface); border-top: 1px solid var(--line); touch-action: none;
}
.sheet-foot > .btn { flex: 1; }
:root .sheet-foot > * { margin-top: 0; margin-bottom: 0; }   /* outranks a part's *-actions margin */
.sheet-ask { display: flex; flex-wrap: wrap; gap: 10px; width: 100%; }
.sheet-ask-text { flex: 1 1 100%; font-weight: 600; }
.sheet-ask .btn { flex: 1; }
/* The map's pin card on a phone is a modeless sheet that stops at the tab bar, so the tabs
   stay tappable under it; it needs no home-bar inset of its own (the tab bar carries it).
   --tabbar-h is the bar's measured height (app.js buildFrame), else the nominal one.
   With no tab bar on show (a one-screen app) it sits on the screen's edge as usual. */
.sheet.modeless.mp-card { bottom: calc(var(--tabbar) + var(--sab)); bottom: var(--tabbar-h, calc(var(--tabbar) + var(--sab))); }
.sheet.modeless.mp-card.no-foot .sheet-body { padding-bottom: var(--gutter); }
.sheet.modeless.mp-card .sheet-foot { padding-bottom: 10px; }
.tabbar-off .sheet.modeless.mp-card { bottom: 0; }
.tabbar-off .sheet.modeless.mp-card.no-foot .sheet-body { padding-bottom: calc(var(--gutter) + var(--sab)); }
.tabbar-off .sheet.modeless.mp-card .sheet-foot { padding-bottom: calc(10px + var(--sab)); }
.sheet h2 { margin: 0 0 6px; font-size: 19px; font-family: var(--font-head); font-weight: var(--head-weight-2); }
.sheet p { margin: 0 0 10px; color: var(--muted); font-size: 15px; }
.sheet .steps { margin: 10px 0 14px; padding: 0; list-style: none; display: grid; gap: 10px; }
.sheet .steps li { display: flex; align-items: center; gap: 12px; font-size: 16px; }
.sheet .steps .step-n {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--btn); color: var(--on-btn); font-weight: 700; font-size: 14px;
}
.sheet .steps svg.ico { color: var(--accent); }
.sheet .sheet-actions { display: flex; gap: 10px; }
.sheet .sheet-actions .btn { flex: 1; }

/* ---- book layout (CHTC7, B6): the place plate (App.plate, SHELL.md "Book layout") and the
   eyebrow label. The .pd-* classes are drawn only when App.layout is "book" (the Folio
   profile); .eyebrow any part may use. Variables only, so every profile carries them; the
   grip, the X and the credit sit on a photo, so they use fixed white and ink. */
.eyebrow {
  font-family: var(--font-label); font-size: var(--label-fs); font-weight: 500; line-height: 1.35;
  letter-spacing: var(--label-spacing); text-transform: uppercase; color: var(--muted);
}
/* the plate in a sheet: the photo runs to the sheet's top and sides; the grip and the X float on it */
.sheet.pd-sheet > .sheet-grip { position: absolute; top: 8px; left: 0; right: 0; z-index: 2; height: 22px; padding-top: 0; }
.sheet.pd-sheet .sheet-handle { background: rgba(255, 255, 255, .85); box-shadow: 0 0 0 .5px rgba(0, 0, 0, .2); }
.sheet.pd-sheet .sheet-x { background: rgba(255, 255, 255, .85); color: #15171c; }
.sheet.pd-sheet .sheet-body { padding-top: 0; }
.sheet.pd-sheet .pd-hero {
  margin-left: calc(-1 * max(var(--gutter), var(--sal)));
  margin-right: calc(-1 * max(var(--gutter), var(--sar)));
}
/* no photo: the plate starts below the X; the grip and X take the sheet's own colours */
.pd.pd-no-photo, .pd.pd-photo-empty { padding-top: 48px; }
.sheet.pd-sheet:has(.pd-no-photo) .sheet-handle, .sheet.pd-sheet:has(.pd-photo-empty) .sheet-handle {
  background: color-mix(in srgb, var(--muted) 45%, transparent); box-shadow: none;
}
.sheet.pd-sheet:has(.pd-no-photo) .sheet-x, .sheet.pd-sheet:has(.pd-photo-empty) .sheet-x { background: var(--surface-2); color: var(--text); }
/* the photo: a 3:2 frame; a URL photo shows its thumb, then the full photo; a Node photo (the
   capture cover or its drawn card) is the frame's only child and fills it */
.pd-hero {
  position: relative; margin: 0 calc(-1 * var(--gutter)) 20px; aspect-ratio: 3 / 2; max-height: 46vh;
  overflow: hidden; background: var(--surface-2); border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
}
.pd-hero > * { display: block; width: 100%; height: 100%; margin: 0; border-radius: 0; }
.pd .pd-hero > :not(.pd-credit) { display: block; width: 100%; height: 100%; margin: 0; border-radius: 0; }
.pd-hero .cap-cover-img { width: 100%; height: 100%; object-fit: cover; }
.pd-hero-img { object-fit: cover; transition: opacity .25s; cursor: pointer; }
.pd-hero[data-state="loading"] .pd-hero-img { opacity: 0; }
.pd-hero > .pd-credit {
  position: absolute; right: 10px; bottom: 8px; display: block; width: auto; height: auto; max-width: calc(100% - 20px);
  margin: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; pointer-events: none;
  font-family: var(--font-label); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: #ffffff; text-shadow: 0 1px 3px rgba(0, 0, 0, .7);
}
/* the words: eyebrow, title, gilt rule, byline with stars, the story first */
.pd-eyebrow { margin: 0 0 8px; }
.sheet .pd h2.pd-title, .pd-title {
  font-family: var(--font-display); font-weight: var(--head-weight); font-size: 28px; line-height: 1.12;
  letter-spacing: var(--head-spacing); margin: 0; color: var(--text); overflow-wrap: anywhere;
}
.pd-rule { width: 32px; height: 1px; background: var(--support); margin: 14px 0 12px; }
.pd-byline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.pd-stars, .pd-score { font-family: var(--font); font-size: 13px; letter-spacing: .08em; text-transform: none; color: var(--text); white-space: nowrap; }
.pd-stars-off { color: var(--muted); }
.pd p.pd-story { margin: 18px 0 0; font-size: 18px; line-height: 1.55; color: var(--text); white-space: pre-line; overflow-wrap: anywhere; }
/* other reviews of the same place, then the small facts */
.pd-reviews { margin: 26px 0 0; }
.pd-reviews-label { margin: 0 0 2px; }
.pd-review { padding: 14px 0; border-top: 1px solid var(--line); }
.pd-review[role="button"] { cursor: pointer; }
.pd-review[role="button"]:active { background: var(--surface-2); }
.pd-review-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.pd-who { font-family: var(--font-display); font-weight: var(--head-weight); font-size: 19px; line-height: 1.2; }
.pd-date { margin-left: auto; }
.pd p.pd-review-text { margin: 6px 0 0; font-size: 16px; line-height: 1.5; color: var(--text); white-space: pre-line; overflow-wrap: anywhere; }
.pd-facts {
  display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; margin: 24px 0 0; padding-top: 16px;
  border-top: 1px solid var(--line); font-size: 15px;
}
.pd-facts dt {
  margin: 0; padding-top: 3px; font-family: var(--font-label); font-size: 10.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.pd-facts dd { margin: 0; overflow-wrap: anywhere; }
.pd-section { margin-top: 18px; }
.pd-actions { display: flex; gap: 10px; margin-top: 24px; }
.pd-actions .btn { flex: 1; }

/* ---- components for parts */
/* About: Photo credits (CHTC7, B7; spec C11): the picture beside a column of place, author and licence, Source */
.list-item.ab-credit { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 2px 12px; align-items: center; }
.ab-credit-thumb { grid-row: 1 / span 3; width: 48px; height: 48px; flex: 0 0 48px; object-fit: cover; border-radius: 8px; background: var(--surface-2); }
.ab-credit > strong, .ab-credit > .muted, .ab-credit > a { grid-column: 2; min-width: 0; }
.ab-credit > a { justify-self: start; display: inline-flex; align-items: center; min-height: 40px; color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.ab-credits-open .grow { flex: 1; min-width: 0; }
.h1 {
  font-family: var(--font-head); font-size: 26px; font-weight: var(--head-weight);
  letter-spacing: var(--head-spacing); text-transform: var(--head-case); margin: 4px 0 12px;
}
.h2 { font-family: var(--font-head); font-size: 18px; font-weight: var(--head-weight-2); margin: 18px 0 8px; }
.muted { color: var(--muted); }
.small { font-size: 14px; }
.card {
  background: var(--surface); border-radius: var(--radius);
  border: var(--card-border-w) solid var(--edge);
  box-shadow: var(--card-shadow); padding: var(--card-pad); margin: 0 0 12px;
}
.card.plain { box-shadow: none; border: max(1px, var(--card-border-w)) solid var(--line); }
.row { display: flex; align-items: center; gap: 10px; }
.row > .grow { flex: 1; min-width: 0; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 18px;
  border: var(--btn-border-w) solid var(--edge); border-radius: var(--radius-btn);
  background: var(--btn); color: var(--on-btn);
  font-weight: var(--btn-weight); font-size: var(--btn-fs); text-decoration: none;
  text-transform: var(--btn-case); letter-spacing: var(--btn-spacing);
  transition: filter .1s, transform .1s;
}
.btn:active { filter: brightness(.92); transform: scale(.985); }
.btn:disabled { opacity: .5; }
.btn.secondary { background: var(--support-soft); color: var(--text); }
.btn.ghost { background: transparent; color: var(--accent); border-color: transparent; }
.btn.danger { background: var(--danger); color: var(--on-danger); }
.btn.block { display: flex; width: 100%; }
.btn.small { min-height: 40px; padding: 0 14px; font-size: 15px; }
.icon-btn {
  width: var(--tap); height: var(--tap); border: 0; border-radius: 50%;
  background: transparent; color: var(--muted);
  display: inline-grid; place-items: center; flex: none;
}
.icon-btn:active { background: var(--surface-2); }
.input, .textarea, .select {
  width: 100%; min-height: var(--tap);
  padding: 0 14px;
  border: var(--field-border-w) solid var(--field-line); border-radius: var(--radius-input);
  background: var(--surface); color: var(--text);
  outline: none;
}
.textarea { padding: 12px 14px; min-height: 96px; resize: vertical; }
.input:focus, .textarea:focus, .select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.list { margin: 0; padding: 0; list-style: none; }
.list-item {
  display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 10px 0;
  border-top: 1px solid var(--line);
  overflow-wrap: anywhere;
}
.list-item:first-child { border-top: 0; }
.list-item .grow { flex: 1; min-width: 0; }
.empty { text-align: center; color: var(--muted); padding: 36px 16px; }
.empty svg.ico { width: 40px; height: 40px; stroke-width: 1.5; margin-bottom: 8px; opacity: .6; }
.badge {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  background: var(--accent-soft); color: var(--accent);
}
.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: 15px; }
.kv dt { color: var(--muted); margin: 0; }
.kv dd { margin: 0; overflow-wrap: anywhere; }
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--accent);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- the profile carried into the parts. Their stylesheets load after this one, so each
   rule is prefixed with :root to outrank them. Headings take the profile's heading face, and
   white text on the warning colour becomes the colour's own readable ink (in dark mode the
   warning colour is lightened so it reads as text, and white on it would not). */
:root .graph-title, :root .tbl-title, :root .fb-head, :root .qr-title, :root .mp-confirm-title, :root .mp-popup-title {
  font-family: var(--font-head);
}
:root .tbl-badge.warn, :root .fb-mic.on, :root .cap-rec { color: var(--on-danger); }
:root .mp-cluster-inner { color: var(--on-accent); }
:root .tbl-fab { border: var(--btn-border-w) solid var(--edge); }
:root .tbl-card, :root .tbl-table-wrap { border: var(--card-border-w) solid var(--edge); box-shadow: var(--card-shadow); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
