/* spashii design system, v1. One stylesheet for the Blend Mic and Dictate sites, served from
   https://spashii.github.io/ds/v1.css. The style guide at https://spashii.github.io/ds/ shows every
   token and component in light and dark.

   v1 only takes fixes. A change in look ships as v2, so each site moves to it on purpose.

   The rules this file enforces:
   - Four text styles: h1, h2, h3 and body. One text colour. Weight only in headings, never bold or italic in body.
   - Hierarchy comes from size, spacing and grouping, never from grey text.
   - Anything underlined is a link. Buttons are capsules and react to hover, press and focus.
   - The primary button is the only coloured element. Drawings of the apps keep the apps' own colours, in page CSS.
   - Space comes from one scale. Sections sit --section apart.
   Page CSS holds only what one page draws (illustrations, demos) and never redefines a token. */

/* Tokens: type, space, layout */
:root {
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter Variable", "Inter", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, "Ubuntu Mono", monospace;

  /* Four sizes. h1 and h2 scale down on a phone; h3 and body never change. */
  --size-h1: clamp(36px, 2.4vw + 26.6px, 48px);
  --size-h2: clamp(24px, 0.8vw + 20.9px, 28px);
  --size-h3: 20px;
  --size-body: 17px;
  --leading-h1: 1.05;
  --leading-h2: 1.15;
  --leading-h3: 1.3;
  --leading-body: 1.5;

  /* Spacing. 8 binds things into a group, 16 separates items in a group, 32 separates groups,
     --section separates sections. The others are for components. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;
  --sp-10: 128px;
  --section: var(--sp-10);

  --page: 980px;     /* content width */
  --measure: 560px;  /* longest line of running text: about 70 characters at 17px */
  --gutter: 24px;
  --nav-top: 24px;   /* gap above the floating nav */
  --nav-h: 52px;
  --top: calc(var(--nav-top) + var(--nav-h) + var(--sp-8)); /* where a page's first heading starts */

  --radius-card: 18px;
  --radius-inner: 12px;
}
@media (max-width: 734px) {
  :root { --gutter: 16px; --section: var(--sp-9); --nav-top: 16px; --top: calc(var(--nav-top) + var(--nav-h) + var(--sp-7)); }
}

/* Tokens: colour. Light is the default; dark follows the system. data-theme forces either on a subtree,
   which the style guide uses to show both side by side. */
:root, [data-theme="light"] {
  color-scheme: light;
  --bg: #ffffff;
  --surface: #f5f5f7;
  --surface-hover: #ebebef;
  --surface-active: #e1e1e6;
  --text: #1d1d1f;
  --hairline: #d2d2d7;
  --control-border: #86868b;
  --fill: rgba(120, 120, 128, .16);
  --fill-hover: rgba(120, 120, 128, .26);
  --fill-active: rgba(120, 120, 128, .38);
  --primary: #0071e3;
  --primary-hover: #0062c4;
  --primary-active: #00539f;
  --on-primary: #ffffff;
  --focus: #1d1d1f;
  --link-line: rgba(29, 29, 31, .55);
  --glass: rgba(255, 255, 255, .72);
  --glass-edge: rgba(0, 0, 0, .08);
  --float: 0 8px 24px rgba(0, 0, 0, .08);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #000000;
    --surface: #1c1c1e;
    --surface-hover: #2c2c2e;
    --surface-active: #3a3a3c;
    --text: #f5f5f7;
    --hairline: #424245;
    --control-border: #8e8e93;
    --fill: rgba(120, 120, 128, .32);
    --fill-hover: rgba(120, 120, 128, .44);
    --fill-active: rgba(120, 120, 128, .56);
    --focus: #f5f5f7;
    --link-line: rgba(245, 245, 247, .5);
    --glass: rgba(28, 28, 30, .72);
    --glass-edge: rgba(255, 255, 255, .12);
    --float: 0 8px 24px rgba(0, 0, 0, .5);
  }
}
[data-theme="dark"] {
  color-scheme: dark;
  --bg: #000000;
  --surface: #1c1c1e;
  --surface-hover: #2c2c2e;
  --surface-active: #3a3a3c;
  --text: #f5f5f7;
  --hairline: #424245;
  --control-border: #8e8e93;
  --fill: rgba(120, 120, 128, .32);
  --fill-hover: rgba(120, 120, 128, .44);
  --fill-active: rgba(120, 120, 128, .56);
  --focus: #f5f5f7;
  --link-line: rgba(245, 245, 247, .5);
  --glass: rgba(28, 28, 30, .72);
  --glass-edge: rgba(255, 255, 255, .12);
  --float: 0 8px 24px rgba(0, 0, 0, .5);
}
[data-theme] { background: var(--bg); color: var(--text); }

/* Base */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--nav-top) + var(--nav-h) + var(--sp-5)); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  background: var(--bg); color: var(--text);
  font: 400 var(--size-body)/var(--leading-body) var(--font);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
  min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column;
}
body > main { flex: 1 0 auto; }
h1, h2, h3 { font-weight: 600; text-wrap: balance; }
h1 { font-size: var(--size-h1); line-height: var(--leading-h1); letter-spacing: -.025em; }
h2 { font-size: var(--size-h2); line-height: var(--leading-h2); letter-spacing: -.015em; }
h3 { font-size: var(--size-h3); line-height: var(--leading-h3); letter-spacing: -.01em; }
p, li { text-wrap: pretty; }
b, strong, em, i, small { font-weight: inherit; font-style: inherit; font-size: inherit; }
img { max-width: 100%; }
[hidden] { display: none !important; }
.nowrap { white-space: nowrap; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* Focus: one ring for everything, in the text colour, 2px out from the edge. */
:focus-visible, .is-focus { outline: 2px solid var(--focus); outline-offset: 2px; }
:where(a):focus-visible, :where(a.is-focus) { border-radius: 4px; }

/* Links: always underlined, in the text colour. The line is lighter at rest and turns solid and
   thicker on hover. Nothing else on a page is underlined. */
:where(a) {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--link-line);
  text-underline-offset: .22em;
  transition: text-decoration-color .15s;
}
:where(a):hover, :where(a.is-hover) { text-decoration-color: currentColor; text-decoration-thickness: 2px; }
:where(a):active, :where(a.is-active) { text-decoration-color: currentColor; text-decoration-thickness: 2px; background: var(--fill); border-radius: 4px; }

/* Buttons: a capsule, one size for actions and a small one for toolbars. Secondary is a neutral
   fill; primary is the one coloured thing on a page. Hover darkens, press darkens further and sinks.
   Disabled drops the fill for a dashed outline and keeps the text colour, so it stays readable and
   never reads as grey text. */
.button {
  appearance: none; -webkit-appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px; padding: 0 22px;
  border: 0; border-radius: 999px;
  background: var(--fill); color: var(--text);
  font: inherit; line-height: 1.2; text-align: center; text-decoration: none; white-space: nowrap;
  cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s, transform .1s;
}
.button.small { min-height: 36px; padding: 0 16px; }
.button:not(:disabled):not(.is-disabled):hover, .button.is-hover { background: var(--fill-hover); }
.button:not(:disabled):not(.is-disabled):active, .button.is-active { background: var(--fill-active); transform: scale(.98); }
.button.primary { background: var(--primary); color: var(--on-primary); }
.button.primary:not(:disabled):not(.is-disabled):hover, .button.primary.is-hover { background: var(--primary-hover); }
.button.primary:not(:disabled):not(.is-disabled):active, .button.primary.is-active { background: var(--primary-active); }
.button:disabled, .button.is-disabled, .button.primary:disabled, .button.primary.is-disabled {
  background: transparent; color: var(--text); border: 1px dashed var(--control-border); padding: 0 21px; cursor: not-allowed; transform: none;
}
.button.small:disabled, .button.small.is-disabled { padding: 0 15px; }
@media (prefers-reduced-motion: reduce) { .button { transition: none; } .button:active, .button.is-active { transform: none; } }

/* A download group: the buttons, then the facts that belong to them (licence, requirements) right
   under them, closer than anything else on the page. Several .meta lines stack as one block. */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.get > .meta:first-of-type { margin-top: var(--sp-3); }
.get > .meta + .meta { margin-top: 0; }
.meta > span { display: block; white-space: nowrap; } /* each fact is its own line and breaks as a whole */
@media (max-width: 734px) { .actions > .button { flex: 1 1 auto; } .meta > span { white-space: normal; } } /* on a phone, buttons fill the row and stack evenly, and a fact longer than the line wraps */

/* Steps after a download: not in the page until the button is pressed (hidden), then they open to
   their height and fade in. Reduced motion shows them at once. */
.steps { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .3s ease, opacity .3s ease; }
.steps.is-open { grid-template-rows: 1fr; opacity: 1; }
.steps > div { min-height: 0; overflow: hidden; }
.steps ol { margin-top: var(--sp-4); padding-left: var(--sp-5); }
.steps li + li { margin-top: var(--sp-2); }
@media (prefers-reduced-motion: reduce) { .steps { transition: none; } }
.aside { margin-top: var(--sp-6); }

/* Page frame */
.skip { position: absolute; z-index: 60; left: var(--gutter); top: -100px; padding: var(--sp-2) var(--sp-4); border-radius: 999px; background: var(--surface); text-decoration: none; }
.skip:focus { top: var(--nav-top); }
main { display: block; width: min(var(--page), 100% - 2 * var(--gutter)); margin: 0 auto; padding-bottom: var(--section); }
main > section + section { margin-top: var(--section); }
.measure { max-width: var(--measure); }
section > h2:not(.sr) + * { margin-top: var(--sp-6); }
p + p { margin-top: var(--sp-4); }

/* Floating glass nav: a capsule with a gap above it. On a wide screen its brand lines up with the
   content edge below. */
.nav {
  position: fixed; z-index: 50; top: var(--nav-top); left: 50%; transform: translateX(-50%);
  width: min(calc(var(--page) + 24px), 100% - 24px); height: var(--nav-h);
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 8px 0 12px; border-radius: 999px;
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 0 0 1px var(--glass-edge), var(--float);
}
.nav .brand { display: inline-flex; align-items: center; gap: var(--sp-2); text-decoration: none; border-radius: 6px; }
.nav .brand img { width: 24px; height: 24px; }
.nav .links { margin-left: auto; display: flex; align-items: center; gap: 20px; }
/* On a phone the brand keeps its icon and hides its name (still read out), so the links stay. */
@media (max-width: 480px) {
  .nav { gap: var(--sp-3); }
  .nav .links { gap: var(--sp-3); }
  .nav .brand .name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* Hero: words on the left, the app on the right, the words centred against the app so the first
   screen reads as one composition; one column on a phone. */
.hero { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--sp-8); align-items: center; padding-top: var(--top); }
.hero .lede { margin-top: var(--sp-5); }
.hero .get { margin-top: var(--sp-6); }
@media (max-width: 834px) { .hero { grid-template-columns: minmax(0, 1fr); gap: var(--sp-7); } }

/* Cards: a flat surface tile, two across so text keeps a readable line and every row fills.
   A drawing inside sits on top in a framed well, then h3, then text. */
.cards { display: grid; gap: var(--sp-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 734px) { .cards { grid-template-columns: minmax(0, 1fr); } .card { padding: 20px; } }
.card { background: var(--surface); border-radius: var(--radius-card); padding: var(--sp-5); }
.card > * + h3 { margin-top: var(--sp-5); }
.card h3 + p { margin-top: var(--sp-2); }
.card.placeholder { background: transparent; box-shadow: inset 0 0 0 1px var(--control-border); }
.card.placeholder > .well { box-shadow: none; border: 1px dashed var(--control-border); }

/* Drawings of the apps always sit in a visible frame: .frame for a hero, .well inside a card. */
.frame { background: var(--surface); border-radius: var(--radius-card); box-shadow: inset 0 0 0 1px var(--hairline); }
.well { height: 144px; overflow: hidden; border-radius: var(--radius-inner); background: var(--bg); box-shadow: inset 0 0 0 1px var(--hairline); }
@media (max-width: 734px) { .well { height: auto; min-height: 144px; } }

/* Questions: a disclosure list between hairlines. The chevron sits in a round fill that reacts like a
   secondary button. */
.faq-list { border-top: 1px solid var(--hairline); }
.faq-list details { border-bottom: 1px solid var(--hairline); }
.faq-list summary { position: relative; display: block; list-style: none; padding: 20px 56px 20px 0; cursor: pointer; border-radius: 8px; -webkit-tap-highlight-color: transparent; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::before { content: ""; position: absolute; right: 0; top: 50%; width: 32px; height: 32px; margin-top: -16px; border-radius: 50%; background: var(--fill); transition: background-color .15s; }
.faq-list summary::after { content: ""; position: absolute; right: 12px; top: 50%; width: 8px; height: 8px; margin-top: -6px; border: solid var(--text); border-width: 0 2px 2px 0; transform: rotate(45deg); transition: transform .2s; }
.faq-list summary:hover::before, .faq-list summary.is-hover::before { background: var(--fill-hover); }
.faq-list summary:active::before { background: var(--fill-active); }
.faq-list details[open] > summary::after { transform: rotate(225deg); margin-top: -2px; }
.faq-list details > :not(summary) { max-width: var(--measure); margin-top: calc(-1 * var(--sp-2)); padding-bottom: var(--sp-5); }
@media (prefers-reduced-motion: reduce) { .faq-list summary::after { transition: none; } }

/* Code: a label with its Copy button on one line, the code in a surface box under it. */
.code-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.code { margin-top: var(--sp-3); border-radius: var(--radius-inner); background: var(--surface); }
.code pre { margin: 0; padding: var(--sp-4); overflow-x: auto; font: 400 var(--size-body)/1.6 var(--mono); }
kbd {
  display: inline-block; white-space: nowrap; min-width: 1.7em; padding: 0 .4em; border-radius: 6px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--hairline), inset 0 -1px 0 var(--hairline);
  font: inherit; line-height: 1.45; text-align: center;
}

/* Other work: each project is a card that is one link. Its name carries the link underline. */
.work { display: grid; gap: var(--sp-4); max-width: var(--measure); }
a.work-item {
  display: flex; gap: var(--sp-4); align-items: flex-start;
  padding: var(--sp-5); border-radius: var(--radius-card); background: var(--surface);
  color: inherit; text-decoration: none; transition: background-color .15s;
}
a.work-item img { flex: none; width: 52px; height: 52px; border-radius: 12px; }
a.work-item h3 { text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: var(--link-line); text-underline-offset: .22em; }
a.work-item h3 + p { margin-top: var(--sp-2); }
a.work-item:hover, a.work-item.is-hover { background: var(--surface-hover); }
a.work-item:hover h3, a.work-item.is-hover h3 { text-decoration-color: currentColor; text-decoration-thickness: 2px; }
a.work-item:active { background: var(--surface-active); }
@media (max-width: 734px) { a.work-item { flex-direction: column; padding: 20px; } }

/* Text fields */
.field + .field { margin-top: var(--sp-5); }
label { display: block; }
label + input { margin-top: var(--sp-2); }
input[type="email"], input[type="text"] {
  display: block; width: 100%; min-height: 44px; padding: 0 16px;
  border: 1px solid var(--control-border); border-radius: var(--radius-inner);
  background: var(--bg); color: var(--text); font: inherit;
}
input[aria-invalid="true"] { border-width: 2px; padding: 0 15px; }

/* Document pages: privacy and the like. */
main.doc { padding-top: var(--top); }
main.doc > * { max-width: var(--doc-measure, var(--measure)); } /* the column starts at the content edge, like the nav brand and the footer */
main.doc > * + * { margin-top: var(--sp-4); }
main.doc > h1 + * { margin-top: var(--sp-5); }
main.doc > h2 { margin-top: var(--sp-7); }
main.doc ul, main.doc ol { padding-left: 24px; }
main.doc li + li { margin-top: var(--sp-2); }

/* Footer: a hairline at the content edge, then one line of who made it and where the source is. */
footer.site { width: min(var(--page), 100% - 2 * var(--gutter)); margin: 0 auto; padding: var(--sp-6) 0 var(--sp-7); border-top: 1px solid var(--hairline); }
