/* Dashboard Atlas hub: gallery, viewer and access pages. Dashboards never load this file. */
:root {
  --ink: #161616;
  --muted: #5f5f66;
  --faint: #6e6e78;
  --line: #e4e4ea;
  --line-strong: #cfcfd8;
  --bg: #ffffff;
  --soft: #f6f6fa;
  --card-hover: #f1f1f7;
  --primary: #3e2df5;
  --primary-soft: #eeecfe;
  /* Landing page light blue: the hero glow, the title marker and the price panel. */
  --sky: #e3efff;
  --sky-soft: #f3f8ff;
  --sky-line: #d6e5f9;
  --sky-mark: #cfe2ff;
  --cta: #ff5c35;
  --cta-hover: #f23a0c;
  --cta-text: #c4320a;
  --good: #1a7f4b;
  --stage: #1d1d22;
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 1px 2px rgb(22 22 22 / 6%), 0 8px 24px rgb(22 22 22 / 6%);
  --font: "Nunito Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  /* Motion: one vocabulary for the hub (docs/DASHBOARD-SPEC.md "Motion" uses the same names). */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --t-press: 120ms;
  --t-hover: 160ms;
  --t-ui: 200ms;
  --t-sheet: 280ms;
  color-scheme: light;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font: 16px/1.55 var(--font);
  color: var(--ink);
  background: var(--bg);
  font-variant-numeric: tabular-nums;
}
a { color: inherit; }
img { max-width: 100%; display: block; }
button, input, select { font: inherit; color: inherit; }
a, button, select, input, summary { touch-action: manipulation; }
/* Focus ring at 3:1 or better on every surface (WCAG 2.2 focus appearance); white on the dark viewer bar. */
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.vbar :focus-visible, .frame-box iframe:focus-visible { outline-color: #fff; }
/* Press feedback on compact pressables; rows get a background step instead (see the spec). */
.btn:active, .icon-btn:active, .seg button:active, .close-sheet:active { transform: scale(.98); }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.wrap { width: min(1200px, 100% - 32px); margin-inline: auto; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 18px; border-radius: 999px; border: 1px solid transparent;
  font-weight: 600; font-size: 15px; text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: transform var(--t-press) var(--ease-out), background-color var(--t-hover), border-color var(--t-hover);
}
.btn-cta { background: var(--cta); color: #fff; }
.btn-cta:hover { background: var(--cta-hover); }
.btn-ghost { background: var(--bg); border-color: var(--line-strong); }
.btn-ghost:hover { background: var(--soft); }
.btn-dark { background: var(--ink); color: #fff; }
.btn svg { width: 18px; height: 18px; flex: none; }
.link { color: var(--primary); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.link[data-buy] { color: var(--cta-text); }
button.link { padding: 0; border: 0; background: none; font: inherit; font-weight: 600; cursor: pointer; }

/* Site header */
.site-header { position: sticky; top: 0; z-index: 20; background: rgb(255 255 255 / 92%); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
.site-header .wrap { display: flex; align-items: center; gap: 16px; min-height: 64px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; min-width: 0; }
.brand img { width: 28px; height: 28px; flex: none; }
.brand .product { font-weight: 800; font-size: 17px; letter-spacing: -0.01em; white-space: nowrap; }
.site-header nav { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.site-header nav .plain { font-size: 15px; font-weight: 600; text-decoration: none; padding: 10px 12px; border-radius: var(--radius-sm); }
.site-header nav .plain:hover { background: var(--soft); }
/* Unlocked: one plain word in the unlocked green, where Get access would be. */
.access-note { font-size: 15px; font-weight: 600; color: var(--good); padding: 10px 4px 10px 12px; white-space: nowrap; }
/* Leaving full access: a quiet text button beside the green word, for a shared or borrowed browser. */
.site-header nav .exit { min-height: 44px; border: 0; background: none; font: inherit; font-size: 15px; font-weight: 600; color: var(--muted); cursor: pointer; }
.site-header nav .exit[hidden] { display: none; }
/* The header button's label shortens on a phone ("Book a session"). */
.site-header .btn .show-sm { display: none; }
@media (max-width: 640px) {
  .site-header nav .plain.hide-sm { display: none; }
  .site-header .btn .hide-sm { display: none; }
  .site-header .btn .show-sm { display: inline; }
  /* With access the header also holds "Full access" and Exit, so the name gives way to the mark. */
  .site-header:has(.exit:not([hidden])) .brand .product { display: none; }
}

/* Hero */
/* Hero: centered copy, a wide stage for the dashboard deck on a faint dot grid, then the offer bar
   overlapping the stage's lower edge. */
.hero { position: relative; padding: 44px 0 8px; overflow: hidden;
  background: radial-gradient(65% 55% at 50% 60%, var(--sky) 0%, rgb(227 239 255 / 0%) 72%), linear-gradient(180deg, var(--sky-soft) 0%, #fff 55%); }
.hero::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(rgb(22 22 22 / 9%) 1px, transparent 1.2px); background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(70% 60% at 50% 55%, #000 30%, transparent 78%); mask-image: radial-gradient(70% 60% at 50% 55%, #000 30%, transparent 78%); }
.hero > * { position: relative; }
.hero-copy { display: grid; justify-items: center; text-align: center; }
.hero h1 { font-size: clamp(36px, 5.4vw, 68px); line-height: 1.05; letter-spacing: -0.035em; margin: 0 0 18px; max-width: 940px; text-wrap: balance; }
/* "command center" on a light blue marker, kept on one line so the marker never breaks. */
.hero h1 em { font-style: normal; white-space: nowrap; background: linear-gradient(transparent 64%, var(--sky-mark) 64%, var(--sky-mark) 88%, transparent 88%); }
.hero p.lead { font-size: clamp(17px, 2vw, 20px); color: var(--muted); max-width: 54ch; margin: 0 0 28px; }
.hero .actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.btn-lg { min-height: 52px; padding: 0 24px; font-size: 16px; }
.hero .price-note { font-size: 15px; color: var(--muted); margin: 14px 0 0; }
/* Launch price pill above the title: the price, a dot and the live countdown; opens checkout. */
.launch-pill { display: inline-flex; align-items: center; gap: 10px; min-height: 40px; margin-bottom: 24px; padding: 0 8px 0 16px; border: 1px solid #ffd6c9; border-radius: 999px; background: #fff; color: var(--cta-text); font-size: 15px; text-decoration: none; box-shadow: 0 1px 2px rgb(22 22 22 / 5%); transition: border-color var(--t-hover), background-color var(--t-hover); }
.launch-pill:hover { background: #fff7f4; border-color: #ffb9a3; }
.launch-pill[hidden] { display: none; }
.launch-pill b { font-weight: 800; }
.launch-pill .dot { width: 4px; height: 4px; border-radius: 50%; background: currentColor; opacity: .5; }
.launch-pill .left { font-weight: 800; font-variant-numeric: tabular-nums; }
.launch-pill svg { width: 26px; height: 26px; padding: 5px; border-radius: 50%; background: var(--cta); color: #fff; flex: none; }
/* The stage is wider than the text column; the deck inside is laid out in landing-motion.css. */
.hero-stage { width: min(1180px, 100% - 32px); margin: 28px auto 0; }
.hero-art { display: none; position: relative; }
/* The offer bar, two panels: the counts on white, then a light blue panel that compares the same
   screens two ways side by side (a freelance designer's cost, grey; full access, white with an
   orange border), the launch price line and the buy button. Locked only; with access the counts
   take the whole bar. */
.offer { position: relative; z-index: 3; margin-top: -48px; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); background: var(--bg); border: 1px solid var(--line); border-radius: 20px; overflow: hidden; box-shadow: 0 1px 2px rgb(22 22 22 / 6%), 0 24px 60px rgb(22 22 22 / 12%); }
.offer:has(.offer-deal[hidden]) { grid-template-columns: minmax(0, 1fr); }
.offer-inside { display: grid; align-content: center; gap: 16px; padding: 26px 32px; }
.o-head { margin: 0; font-size: 15px; font-weight: 700; color: var(--muted); }
.offer-stats { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.offer-stats li { padding: 0 0 0 20px; border-left: 1px solid var(--line); font-size: 15px; color: var(--muted); line-height: 1.25; }
.offer-stats li:first-child { padding-left: 0; border-left: 0; }
.offer-stats b { display: block; font-size: clamp(30px, 3.4vw, 40px); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; color: var(--ink); }
/* What comes with it: a short tick list under the counts. */
.o-list { list-style: none; margin: 6px 0 0; padding: 18px 0 0; border-top: 1px solid var(--line); display: grid; gap: 10px; }
.o-list li { display: flex; align-items: flex-start; gap: 10px; font-size: 15px; line-height: 1.4; }
/* A white tick in a filled green circle. */
.o-list li::before { content: ""; flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 50%; background: var(--good) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.5 10.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat; }
.offer-deal { display: grid; align-content: center; gap: 14px; padding: 24px 32px; background: var(--sky-soft); border-left: 1px solid var(--sky-line); }
.offer-deal[hidden] { display: none; }
.compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.compare > div { display: grid; align-content: start; gap: 2px; padding: 14px 16px; border-radius: var(--radius-sm); }
.c-them { background: rgb(255 255 255 / 60%); border: 1px solid var(--sky-line); }
.c-us { background: var(--bg); border: 2px solid var(--cta); box-shadow: 0 8px 24px rgb(255 92 53 / 14%); }
.c-who { font-size: 15px; font-weight: 700; color: var(--muted); }
.c-us .c-who { color: var(--ink); }
.c-total { font-size: clamp(28px, 3vw, 38px); font-weight: 800; letter-spacing: -0.03em; line-height: 1.15; color: var(--muted); }
.c-us .c-total { color: var(--cta-text); }
.c-per { font-size: 14px; color: var(--muted); }
.c-us .c-per span { color: var(--ink); font-weight: 700; }
/* The bonus: a dashed row under the comparison, the word Bonus as a small orange tag. */
.bonus { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; border: 1px dashed #a9c7ef; border-radius: var(--radius-sm); background: rgb(255 255 255 / 70%); }
.b-tag { flex: none; padding: 3px 9px; border-radius: 999px; background: var(--cta); color: #fff; font-size: 14px; font-weight: 800; line-height: 1.3; }
.bonus p { margin: 0; font-size: 15px; color: var(--muted); }
.bonus b { color: var(--ink); }
.r-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; padding-top: 14px; border-top: 1px solid var(--sky-line); }
.r-foot p { margin: 0; font-size: 15px; color: var(--muted); }
.r-foot b { color: var(--ink); }
.r-foot .btn { margin-left: auto; }
.offer-foot { margin: 14px 0 0; text-align: center; font-size: 14px; color: var(--faint); }
@media (max-width: 960px) {
  .offer { grid-template-columns: minmax(0, 1fr); }
  .offer-deal { border-left: 0; border-top: 1px solid var(--sky-line); }
}
@media (max-width: 640px) {
  .hero { padding-top: 36px; }
  .hero .actions { width: 100%; }
  .hero .actions .btn { flex: 1 1 100%; }
  .launch-pill { font-size: 14px; gap: 8px; padding: 0 14px; white-space: nowrap; }
  .launch-pill .ends, .launch-pill svg { display: none; }
  .offer { margin-top: -24px; }
  .offer-inside, .offer-deal { padding: 18px 16px; }
  .offer-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 14px; }
  .offer-stats li:nth-child(3) { padding-left: 0; border-left: 0; }
  .compare { gap: 8px; }
  .compare > div { padding: 12px; }
  .r-foot .btn { flex: 1 1 100%; }
}

/* Filter bar (pinned while the list scrolls). Controls are 44px on touch, 40px with a mouse. */
.toolbar { --ctl: 44px; position: sticky; top: 64px; z-index: 10; background: var(--bg); border-bottom: 1px solid var(--line); scroll-margin-top: 64px; }
@media (pointer: fine) { .toolbar { --ctl: 40px; } }
.toolbar .wrap { display: flex; flex-wrap: wrap; align-items: end; gap: 12px; padding-block: 12px; }
/* Underline tabs with plain grey counts. The underline sits on the bar's own bottom rule. */
.tabs { display: flex; gap: 24px; margin: 0 12px -13px 0; }
.tabs button { display: inline-flex; align-items: center; gap: 6px; min-height: calc(var(--ctl) + 13px); padding: 0 0 11px; border: 0; border-bottom: 2px solid transparent; background: none; font-weight: 600; font-size: 15px; cursor: pointer; color: var(--muted); transition: color var(--t-hover), border-color var(--t-hover); }
.tabs button:hover, .tabs button:active { color: var(--ink); }
.tabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--ink); }
.tabs .count { font-weight: 400; color: var(--faint); }
.field { display: grid; gap: 4px; }
.field label { font-size: 14px; font-weight: 600; color: var(--muted); }
.field select, .field input { min-height: var(--ctl, 44px); padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: var(--bg); min-width: 0; }
.field select { max-width: 200px; text-overflow: ellipsis; }
.field input { width: 100%; }
.field.search { flex: 1 1 180px; min-width: 160px; max-width: 320px; }
.clear { display: none; align-items: center; gap: 6px; min-height: var(--ctl); border: 0; background: none; color: var(--primary); font-weight: 600; font-size: 14px; cursor: pointer; }
.clear.on { display: inline-flex; }
/* "4 of 11 dashboards" only while a filter is on; the tab count already says the total. */
.result-count { margin-left: auto; display: inline-flex; align-items: center; min-height: var(--ctl); font-size: 14px; color: var(--muted); }
.result-count:empty { display: none; }
/* Below 1232px the bar can wrap (Clear and the count need the room), so the tabs take their own
   row with their own rule, and the filters sit under them. */
@media (max-width: 1231px) {
  .tabs { flex: 1 1 100%; margin: 0; border-bottom: 1px solid var(--line); }
  .tabs button { min-height: 48px; padding: 0; margin-bottom: -1px; }
}
@media (max-width: 720px) {
  .toolbar { position: static; }
  .toolbar .wrap > * { flex: 1 1 100%; }
  /* Industry and role side by side, so the notes start higher up the page */
  .toolbar .wrap > .field.pick { flex: 1 1 calc(50% - 6px); min-width: 0; }
  .field select { max-width: none; width: 100%; }
  .field.search { min-width: 0; max-width: none; }
  .result-count { margin-left: 0; }
}

/* Gallery grid: three columns at 1440; the thumbnail is framed and the words sit on the page under it. */
.section { padding: 28px 0 56px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 40px 28px; }
.card { position: relative; isolation: isolate; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.card .shot { position: relative; aspect-ratio: 16 / 10; background: var(--soft); overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius); transition: border-color var(--t-hover); }
/* The card's area: a soft fill 12px around the frame and the words under it, shown on hover and
   while the card has keyboard focus, so it is clear the words belong to the picture above them. */
.card::before { content: ""; position: absolute; inset: -12px; z-index: -1; border-radius: calc(var(--radius) + 6px); background: var(--card-hover); opacity: 0; transition: opacity var(--t-hover); }
.card:focus-within::before { opacity: 1; }
/* Hover is a fill, a border step and the title's underline, never a lift or a shadow, and only for
   a real pointer: touch fires hover on tap and would leave the card stuck. */
@media (hover: hover) and (pointer: fine) {
  .card:hover::before { opacity: 1; }
  .card:hover .shot { border-color: var(--line-strong); }
  .card:hover h3 a { text-decoration: underline; text-underline-offset: 3px; }
}
.card .shot img { width: 100%; height: 100%; object-fit: cover; object-position: top left; }
.card .shot .placeholder { position: absolute; inset: 0; display: grid; place-items: center; color: var(--faint); font-weight: 600; }
.card .body { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 0 2px; }
.card .head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.card h3 { margin: 0; font-size: 17px; font-weight: 700; line-height: 1.35; }
.card h3 a { text-decoration: none; }
.card h3 a::after { content: ""; position: absolute; inset: 0; }
/* Access is one word on the heading's line: green when it is free to open, muted when locked. */
.card .state { display: inline-flex; align-items: center; gap: 5px; flex: none; font-size: 14px; font-weight: 600; color: var(--muted); }
.card .state svg { width: 14px; height: 14px; }
.card .state.free { color: var(--good); }
.card .line { margin: 4px 0 0; font-size: 15px; color: #45454c; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.card .meta { margin: 2px 0 0; font-size: 14px; color: var(--faint); }

/* Design notes tab: styles live in hub/ideas.css */

/* Empty state */
.empty { text-align: center; padding: 48px 16px; border: 1px dashed var(--line-strong); border-radius: var(--radius); color: var(--muted); }
.empty h3 { color: var(--ink); margin: 12px 0 4px; }
.empty svg { width: 36px; height: 36px; color: var(--faint); }

/* Coming next + how it works + FAQ */
.band { background: var(--soft); padding: 56px 0; }
.band h2, .section h2, .lib-head h2 { font-size: clamp(24px, 3vw, 32px); letter-spacing: -0.02em; margin: 0 0 8px; }
/* The library's heading, above the pinned filter bar. */
.lib-head { padding-top: 48px; scroll-margin-top: 64px; }
.band p.sub, .section p.sub, .lib-head p.sub { color: var(--muted); margin: 0 0 24px; max-width: 62ch; }
/* Coming next is a plain list in columns, not a wall of boxes: name, then what it would track. */
/* Two ways: build it yourself and done for you, as two bordered columns with the same shape
   (name and price line, three numbered steps, one button). One column under 900px. Numbers are
   plain text in ink circles, like How it works; no step cards inside. */
.plan { border-top: 1px solid var(--line); padding-top: 56px; scroll-margin-top: 64px; }
.paths { display: grid; gap: 20px; }
@media (min-width: 900px) { .paths { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.path { display: grid; grid-template-rows: auto 1fr auto; gap: 18px; padding: 24px 26px 26px; border: 1px solid var(--line); border-radius: var(--radius); scroll-margin-top: 80px; }
.path .btn { justify-self: start; }
.path-head h3 { margin: 0; font-size: 22px; letter-spacing: -0.01em; }
.path-head p { margin: 2px 0 0; font-weight: 600; color: var(--muted); }
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps li { counter-increment: step; display: grid; grid-template-columns: 24px minmax(0, 1fr); column-gap: 14px; padding: 16px 0; border-top: 1px solid var(--line); }
.steps li:first-child { border-top: 0; padding-top: 4px; }
.steps li::before { content: counter(step); grid-row: 1 / span 2; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--ink); color: #fff; font-size: 14px; font-weight: 700; line-height: 1; margin-top: 1px; }
.steps h4 { margin: 0; font-size: 17px; line-height: 1.4; }
.steps p { margin: 4px 0 0; color: var(--muted); max-width: 56ch; }

.soon { columns: 3 260px; column-gap: 40px; padding: 0; margin: 0; list-style: none; border-top: 1px solid var(--line); }
.soon li { break-inside: avoid; padding: 12px 0; border-bottom: 1px solid var(--line); }
.soon strong { display: block; font-weight: 700; }
.soon span { font-size: 14px; color: var(--muted); }
/* How it works: one real screen with three regions marked, beside the notes that explain them. */
#how { scroll-margin-top: 64px; }
#faq { scroll-margin-top: 96px; }
.how { display: grid; gap: 28px; }
@media (min-width: 1000px) { .how { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 48px; align-items: center; } }
.how-shot { position: relative; margin: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.how-shot img { width: 100%; height: auto; border-radius: calc(var(--radius) - 1px); }
/* Regions in percent of the 1440x900 capture (hub/how-shot.webp); re-measure when it is re-shot. */
.how-mark { position: absolute; border: 2px solid var(--primary); border-radius: 6px; cursor: pointer; transition: opacity var(--t-hover), background-color var(--t-hover); }
.how-mark.m1 { left: .83%; top: 8.56%; width: 15.76%; height: 6.89%; }
.how-mark.m2 { left: 83.61%; top: 13.58%; width: 14.44%; height: 4.44%; }
.how-mark.m3 { left: 75.69%; top: 38.11%; width: 4.03%; height: 61.89%; }
.how-mark b, .how-list li::before { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--primary); color: #fff; font-size: 14px; font-weight: 700; line-height: 1; }
.how-mark b { position: absolute; top: -13px; left: -13px; }
.how-list { list-style: none; margin: 0; padding: 0; counter-reset: how; }
.how-list li { counter-increment: how; display: grid; grid-template-columns: 24px minmax(0, 1fr); column-gap: 14px; padding: 18px 0 6px; border-top: 1px solid var(--line-strong); }
.how-list li:first-child { border-top: 0; padding-top: 0; }
/* A mark and its note are one pair: pointing at either (or focusing the note's link, or tapping on
   a touch screen) tints both and fades the other two pairs, so it is clear which note explains which
   part of the screen. gallery.js howPairs sets .how[data-on] and .on. */
.how-list li { margin-inline: -14px; padding-inline: 14px; border-radius: var(--radius-sm); transition: opacity var(--t-hover), background-color var(--t-hover); }
.how-list li:first-child { padding-top: 14px; }
.how-list li.on { background: var(--primary-soft); }
.how-list li.on + li { border-top-color: transparent; }
.how[data-on] .how-list li:not(.on) { opacity: .45; }
.how-mark.on { background: rgb(62 45 245 / 12%); }
.how[data-on] .how-shot .how-mark:not(.on) { opacity: .3; }
.how-list li::before { content: counter(how); grid-row: 1 / span 3; margin-top: 1px; }
.how-list h3 { margin: 0; font-size: 16px; line-height: 1.4; }
.how-list p { margin: 4px 0 0; font-size: 15px; color: var(--muted); }
.how-list a { justify-self: start; display: inline-flex; align-items: center; min-height: 44px; color: var(--primary); font-weight: 600; font-size: 15px; text-decoration: none; text-underline-offset: 3px; }
.how-list a:hover { text-decoration: underline; }
@media (max-width: 520px) {
  .how-mark { border-width: 1.5px; border-radius: 4px; }
  .how-mark b { width: 22px; height: 22px; top: -11px; left: -11px; }
}
.faq details { border-bottom: 1px solid var(--line); padding: 14px 0; }
.faq summary { cursor: pointer; font-weight: 600; font-size: 17px; min-height: 32px; }
.faq details p { color: var(--muted); margin: 8px 0 0; max-width: 70ch; }
.cta-band { background: var(--stage); color: #fff; border-radius: var(--radius); padding: 36px clamp(20px, 4vw, 48px); display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between; }
.cta-band h2 { color: #fff; margin: 0 0 6px; }
.cta-band p { color: #c9c9d2; margin: 0; }
.cta-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.site-footer { border-top: 1px solid var(--line); padding: 28px 0 40px; color: var(--muted); font-size: 14px; }
.site-footer .wrap { display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; }

/* Viewer */
body.viewer { background: var(--stage); color: #ececf1; height: 100dvh; overflow: hidden; display: grid; grid-template-rows: auto 1fr; }
.vbar { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: #121215; border-bottom: 1px solid #2b2b32; min-height: 56px; }
.vbar .back { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; font-weight: 600; font-size: 14px; padding: 10px 10px; border-radius: var(--radius-sm); color: #ececf1; white-space: nowrap; }
.vbar .back:hover { background: #24242b; }
.vbar .back svg { width: 18px; height: 18px; }
.vbar .title { min-width: 0; display: grid; }
.vbar .title strong { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vbar .title span { font-size: 14px; color: #9b9ba6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vbar .spacer { flex: 1; }
.seg { display: flex; padding: 4px; background: #24242b; border-radius: var(--radius-sm); }
.seg button { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; min-width: 40px; justify-content: center; padding: 0 10px; border: 0; background: none; color: #a9a9b4; border-radius: calc(var(--radius-sm) - 4px); cursor: pointer; font-size: 14px; font-weight: 600; transition: transform var(--t-press) var(--ease-out), background-color var(--t-hover), color var(--t-hover); }
.seg button[aria-pressed="true"] { background: #3a3a44; color: #fff; }
.seg svg { width: 17px; height: 17px; }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 44px; min-height: 44px; padding: 0 10px; border-radius: var(--radius-sm); border: 1px solid #34343d; background: #1c1c21; color: #ececf1; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: 600; transition: transform var(--t-press) var(--ease-out), background-color var(--t-hover); }
.icon-btn:hover { background: #2a2a31; }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn[disabled] { opacity: .4; cursor: default; }
.vmain { display: grid; grid-template-columns: 1fr 380px; min-height: 0; }
.stage { position: relative; min-width: 0; min-height: 0; display: grid; place-items: center; padding: 20px; overflow: hidden; }
.frame-box { position: relative; transform-origin: center center; box-shadow: 0 30px 80px rgb(0 0 0 / 45%); border-radius: var(--radius); overflow: hidden; background: #fff; flex: none; }
.frame-box.phone { border-radius: 36px; border: 10px solid #0b0b0d; }
.frame-box iframe { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
/* Loading placeholder: the dashboard's own thumbnail (desktop, first screen) or a calm skeleton,
   faded out by hub/view.js once the frame has loaded. */
.frame-wait { position: absolute; inset: 0; z-index: 1; overflow: hidden; background: #fff; transition: opacity var(--t-sheet) var(--ease-out); }
.frame-box.loaded .frame-wait { opacity: 0; pointer-events: none; }
.frame-wait img { display: none; width: 100%; height: auto; }
.frame-box[data-device="desktop"] .frame-wait.has-img img { display: block; }
.frame-box[data-device="desktop"] .frame-wait.has-img .sk { display: none; }
.sk { position: absolute; inset: 0; display: flex; }
.sk i, .sk-side, .sk-bar, .sk-title { display: block; }
.sk-side { flex: none; width: 232px; background: var(--soft); border-right: 1px solid var(--line); }
.sk-main { flex: 1; min-width: 0; display: grid; align-content: start; gap: 20px; padding: 24px 28px; }
.sk-bar { height: 44px; border-radius: var(--radius-sm); background: var(--soft); }
.sk-title { width: 32%; height: 28px; border-radius: var(--radius-sm); background: var(--line); }
.sk-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.sk-cards i { height: 92px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--soft); }
.sk-panels { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; }
.sk-panels i { height: 340px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--soft); }
.sk-bar, .sk-title, .sk-cards i, .sk-panels i { animation: sk-breathe 1.4s ease-in-out infinite alternate; }
.frame-box.loaded .sk * { animation: none; }
.frame-box:not([data-device="desktop"]) .sk-side { display: none; }
.frame-box:not([data-device="desktop"]) .sk-main { padding: 16px; gap: 16px; }
.frame-box:not([data-device="desktop"]) .sk-cards { grid-template-columns: repeat(2, 1fr); }
.frame-box:not([data-device="desktop"]) .sk-panels { grid-template-columns: 1fr; }
.frame-box:not([data-device="desktop"]) .sk-title { width: 60%; }
@keyframes sk-breathe { to { opacity: .55; } }
/* Reduced motion: the skeleton stops breathing and the placeholder still fades, only faster. */
@media (prefers-reduced-motion: reduce) { .sk * { animation: none !important; } .frame-wait { transition-duration: 120ms; } }
.notes { background: #f7f7fa; color: var(--ink); border-left: 1px solid #2b2b32; display: grid; grid-template-rows: auto 1fr; min-height: 0; }
.notes header { padding: 16px 18px 12px; border-bottom: 1px solid var(--line); background: #fff; }
.notes header h2 { margin: 0; font-size: 17px; }
.notes header h2 .count { font-weight: 400; color: var(--faint); margin-left: 4px; }
/* What the dashboard is about sits in the scroll above the screens: the case, then who it is for. */
.notes .about { margin: 2px 4px 6px; display: grid; gap: 6px; font-size: 15px; }
.notes .about p { margin: 0; }
.notes .for { margin: 2px 4px 4px; color: var(--muted); font-size: 14px; }
.notes .scroll { overflow: auto; padding: 14px 14px 24px; display: grid; gap: 10px; align-content: start; }
.notes h3.group { font-size: 14px; font-weight: 600; color: var(--muted); margin: 10px 4px 2px; }
/* Inside the notes panel everything sits at --radius-sm; the screen buttons step down from the list's edge. */
.screens { list-style: none; margin: 0; padding: 4px; columns: 2; column-gap: 4px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.screens li { break-inside: avoid; }
.screens button { width: 100%; min-height: 44px; padding: 10px; display: flex; gap: 8px; align-items: baseline; text-align: left; border: 0; border-radius: calc(var(--radius-sm) - 4px); background: none; color: var(--ink); cursor: pointer; font-size: 14px; font-weight: 400; line-height: 1.3; transition: background-color var(--t-hover), color var(--t-hover); }
.screens button .n { flex: none; min-width: 1.3em; color: var(--muted); font-variant-numeric: tabular-nums; }
.screens button:not([disabled]):hover { background: var(--soft); }
.screens button:not([disabled]):active { background: var(--line); }
/* The current screen reads like the selected note: a violet tint, bold, its number in violet. */
.screens button[aria-current="true"] { background: var(--primary-soft); font-weight: 700; }
.screens button[aria-current="true"] .n { color: var(--primary); }
.screens button[disabled] { cursor: default; }
/* Design notes and Screens are two underline tabs in the panel header. Notes for the screen on show
   come first ("On this screen"); the rest are grouped by category. Each note is one white row with
   hairlines between: its title and first sentence, and a chevron that opens the rest of the text and
   the screen it is about. Beside the dashboard, opening a note also shows that screen. */
.ntabs { display: flex; gap: 22px; margin-bottom: -13px; }
.ntabs button { min-height: 44px; padding: 0 0 10px; border: 0; border-bottom: 2px solid transparent; background: none; font: inherit; font-size: 16px; font-weight: 600; color: var(--muted); cursor: pointer; transition: color var(--t-hover), border-color var(--t-hover); }
.ntabs button:hover { color: var(--ink); }
.ntabs button[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--ink); }
.ntabs .count { font-weight: 400; color: var(--faint); margin-left: 2px; }
.npane { display: grid; gap: 10px; }
.npane[hidden] { display: none; }
#v-patterns { display: grid; gap: 14px; }
.ngroup { display: grid; gap: 6px; }
.ngroup h3.group { margin: 0 4px; }
.ngroup .count { font-weight: 400; color: var(--faint); }
.ngroup:first-child h3.group { margin-top: 2px; }
.notes-list { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.note { position: relative; padding: 12px 14px 12px 16px; display: grid; gap: 4px; border-top: 1px solid var(--line); transition: background-color var(--t-hover); }
.note:first-child { border-top: 0; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.note:last-child { border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
.note:only-child { border-radius: var(--radius-sm); }
.note h4 { margin: 0; font-size: 15px; line-height: 1.4; }
.note .ntoggle { display: flex; gap: 10px; align-items: flex-start; justify-content: space-between; width: 100%; padding: 0; border: 0; background: none; text-align: left; font: inherit; font-weight: 600; color: inherit; cursor: pointer; }
.note .ntoggle::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.note .ntoggle svg { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--faint); transition: transform var(--t-ui) var(--ease-out); }
.note.open .ntoggle svg { transform: rotate(180deg); }
.note .ntoggle:focus-visible { outline: 0; }
.note:has(.ntoggle:focus-visible) { outline: 2px solid var(--primary); outline-offset: -2px; }
.note p { margin: 0; font-size: 14px; color: var(--muted); }
/* Closed, a note is its title and two lines of its first sentence; open, all of it. */
.note:not(.open) .gist { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.note .rest, .note .where { display: none; }
.note.open .rest { display: block; }
.note.open .where { display: inline-flex; }
/* The screen name is a real button above the row's toggle layer, so it stays clickable. */
.note .where { position: relative; z-index: 1; justify-self: start; align-items: center; min-height: 32px; margin-top: 2px; padding: 0; border: 0; background: none; font: inherit; font-size: 14px; font-weight: 600; color: var(--primary); cursor: pointer; text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px; transition: text-decoration-color var(--t-hover); }
.note p.where { color: var(--faint); font-weight: 400; }
@media (hover: hover) and (pointer: fine) {
  .note:hover { background: var(--soft); }
  .note button.where:hover { text-decoration-color: currentColor; }
}
.note:active { background: var(--line); }
.note.active, .note.active:hover { background: var(--primary-soft); }
@media (pointer: coarse) { .note .where { min-height: 44px; } }
.notes-toggle { display: none; }
.notes-toggle span { font-weight: 400; color: #a9a9b4; }
.lock { position: absolute; inset: 0; display: grid; place-items: center; padding: 20px; background: rgb(18 18 21 / 70%); backdrop-filter: blur(6px); z-index: 5; }
.lock[hidden] { display: none; }
.lock .panel { background: #fff; color: var(--ink); width: min(440px, 100%); border-radius: var(--radius); padding: 28px 24px; box-shadow: var(--shadow); display: grid; gap: 14px; text-align: center; }
.lock .panel h2 { margin: 0; font-size: 22px; }
.lock .panel p { margin: 0; color: var(--muted); }
.lock .preview-img { border-radius: var(--radius-sm); border: 1px solid var(--line); }
@media (max-width: 1080px) {
  .vmain { grid-template-columns: 1fr; }
  /* The sheet glides in on the drawer curve and leaves a touch faster. */
  .notes { position: fixed; left: 0; right: 0; bottom: 0; max-height: 72dvh; border-left: 0; border-radius: var(--radius) var(--radius) 0 0; box-shadow: 0 -20px 60px rgb(0 0 0 / 40%); transform: translateY(105%); transition: transform var(--t-ui) var(--ease-drawer); z-index: 30; }
  .notes.open { transform: none; transition-duration: var(--t-sheet); }
  .notes-toggle { display: inline-flex; }
  .notes .close-sheet { display: inline-flex; }
}
@media (min-width: 1081px) { .notes .close-sheet { display: none; } }
.notes header .head-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.close-sheet { border: 0; background: var(--soft); border-radius: var(--radius-sm); min-width: 44px; min-height: 44px; cursor: pointer; align-items: center; justify-content: center; transition: transform var(--t-press) var(--ease-out), background-color var(--t-hover); }
@media (max-width: 760px) {
  .vbar { gap: 6px; padding: 6px 8px; }
  .vbar .title { flex: 1; }
  .vbar .spacer, .vbar .hide-sm, #v-full { display: none; }
  .vbar .back { padding: 10px 6px; }
  .stage { padding: 0; }
}

/* Toast: opacity and transform only, as transitions (it can fire twice in a second); the exit
   runs at about 70 percent of the entrance. */
.toast { position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 20px); opacity: 0; background: var(--ink); color: #fff; padding: 12px 18px; border-radius: var(--radius-sm); font-size: 15px; transition: opacity calc(var(--t-ui) * .7) var(--ease-out), transform calc(var(--t-ui) * .7) var(--ease-out); z-index: 50; pointer-events: none; max-width: calc(100vw - 32px); }
.toast.show { opacity: 1; transform: translate(-50%, 0); transition-duration: var(--t-ui); }

/* Reduced motion: drop the travel, keep the fades, short. */
@media (prefers-reduced-motion: reduce) {
  .toast { transform: translate(-50%, 0); transition-duration: 120ms; }
  .notes { transition: none; }
  .btn:active, .icon-btn:active, .seg button:active, .close-sheet:active { transform: none; }
}

/* Access page (and 404): plain text on the white page, lined up with the logo, no card. */
.access-card { max-width: 480px; margin: 72px 0 96px; display: grid; gap: 14px; }
.access-card h1 { margin: 0; font-size: clamp(28px, 4vw, 36px); line-height: 1.15; letter-spacing: -0.02em; }
.access-card > .btn, .access-card form.unlock .btn { justify-self: start; }
@media (max-width: 640px) { .access-card { margin: 40px 0 64px; } }
.access-card p { margin: 0; color: var(--muted); }
.access-card p.left-note { color: var(--ink); font-weight: 600; }
form.unlock { display: grid; gap: 10px; text-align: left; }
form.unlock label { font-weight: 600; font-size: 15px; }
form.unlock input { min-height: 48px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); font-size: 17px; letter-spacing: .04em; text-transform: uppercase; }
form.unlock .error { color: #b42318; font-size: 15px; margin: 0; min-height: 1em; }
form.unlock button[aria-busy="true"] { opacity: .7; cursor: progress; }

[hidden] { display: none !important; }
