/*
 * itfanatic.com — shared stylesheet.
 *
 * Derived from the PrivacyFirst Photo Organizer user guide's stylesheet
 * (BL_Image_Organizer/docs/howto/style.css), so the marketing site and the
 * guide read as one product. Same indigo accent, same slate neutrals, same
 * semantic colours (amber "needs attention", emerald "done", red
 * "destructive") as the application itself — a screenshot and the prose around
 * it therefore agree about what a colour means.
 *
 * The guide keeps its OWN copy of that stylesheet at
 * /image-organizer/howto/style.css. That is deliberate: the guide is generated
 * in the app repo and copied here verbatim by `npm run howto:sync`, so it has
 * to stay self-contained. Two files, one design system.
 *
 * NO web fonts, NO CDN, NO external requests of any kind. Every page here is
 * served straight off the asset CDN and must stay that way. A landing page that
 * phones out to a third party for a font is also a page that leaks a visitor's
 * IP to that third party, which /privacy would then have to disclose. System
 * fonts avoid the whole question.
 */

/* ------------------------------------------------------------------ tokens -- */

:root {
  --accent: #4f46e5;
  --accent-hover: #4338ca;
  --accent-soft: #eef2ff;
  --accent-border: #c7d2fe;
  --accent-ink: #ffffff;

  --bg: #ffffff;
  --bg-alt: #f8fafc;
  --surface: #ffffff;
  --border: #e2e8f0;
  --border-strong: #cbd5e1;

  --text: #0f172a;
  --text-muted: #475569;
  --text-faint: #64748b;

  --warning: #b45309;
  --warning-bg: #fffbeb;
  --warning-border: #fcd34d;

  --success: #047857;
  --success-bg: #ecfdf5;
  --success-border: #6ee7b7;

  --danger: #b91c1c;
  --danger-bg: #fef2f2;
  --danger-border: #fca5a5;

  --code-bg: #f1f5f9;

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 8px 24px rgba(15, 23, 42, 0.06);
  --shadow-lg: 0 2px 4px rgba(15, 23, 42, 0.06), 0 18px 48px rgba(15, 23, 42, 0.12);

  --page-max: 1120px;
  --prose-max: 720px;
  --radius: 10px;
  --radius-lg: 14px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --accent: #818cf8;
    --accent-hover: #a5b4fc;
    --accent-soft: #1e1b4b;
    --accent-border: #3730a3;
    --accent-ink: #0b1120;

    --bg: #0b1120;
    --bg-alt: #111827;
    --surface: #111827;
    --border: #1f2937;
    --border-strong: #334155;

    --text: #f1f5f9;
    --text-muted: #94a3b8;
    --text-faint: #64748b;

    --warning: #fbbf24;
    --warning-bg: #1c1917;
    --warning-border: #78350f;

    --success: #34d399;
    --success-bg: #052e24;
    --success-border: #065f46;

    --danger: #f87171;
    --danger-bg: #2a1212;
    --danger-border: #7f1d1d;

    --code-bg: #1e293b;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 2px 4px rgba(0, 0, 0, 0.5), 0 18px 48px rgba(0, 0, 0, 0.45);
  }
}

/* ------------------------------------------------------------------- base -- */

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Clears the sticky header when jumping to #buy — the app's Buy button
     lands on exactly that anchor, so it must not arrive underneath the bar. */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

.wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 32px;
}

/* A reading measure. Nest it INSIDE .wrap — never combine them on one element.
   `class="wrap prose"` resolves to a 720px box that still inherits .wrap's
   `margin: 0 auto`, so the section quietly centres itself while every other
   section on the page stays left-aligned. */
.prose {
  max-width: var(--prose-max);
}

.center {
  margin-left: auto;
  margin-right: auto;
}

/* ------------------------------------------------------------- typography -- */

h1 {
  font-size: clamp(2.1rem, 5.2vw, 3.1rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0 0 14px;
  font-weight: 800;
}

h2 {
  font-size: clamp(1.5rem, 3.2vw, 1.95rem);
  line-height: 1.25;
  letter-spacing: -0.015em;
  margin: 0 0 10px;
  font-weight: 700;
}

h3 {
  font-size: 1.18rem;
  line-height: 1.35;
  margin: 0 0 6px;
  font-weight: 700;
}

h4 {
  font-size: 1rem;
  margin: 24px 0 2px;
  font-weight: 700;
}

p {
  margin: 12px 0;
}

.lede {
  font-size: clamp(1.06rem, 2.1vw, 1.24rem);
  line-height: 1.55;
  color: var(--text-muted);
  margin: 14px 0 26px;
}

.eyebrow {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 12px;
}

.meta {
  color: var(--text-faint);
  font-size: 0.88rem;
}

.section-intro {
  color: var(--text-muted);
  max-width: var(--prose-max);
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

strong {
  font-weight: 650;
}

ul,
ol {
  margin: 12px 0;
  padding-left: 22px;
}

li {
  margin: 6px 0;
}

code,
kbd,
.ui {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    monospace;
  font-size: 0.875em;
}

code {
  background: var(--code-bg);
  padding: 2px 5px;
  border-radius: 4px;
}

kbd {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 0.8em;
  white-space: nowrap;
}

/* A button or control exactly as it is labelled inside the application.
   Matches the guide's .ui, so "About → Import license…" looks the same on the
   thanks page, in the guide, and in the purchase email. */
.ui {
  font-family: inherit;
  font-size: 0.94em;
  font-weight: 600;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent-border);
  border-radius: 5px;
  padding: 1px 7px;
  white-space: nowrap;
}

/* A long label that will NOT fit a narrow column unbroken.
   `.ui` is nowrap on purpose — a control's name should not be split across
   lines — but "Allow executing file as program" is 31 characters and the Linux
   download card is one of FOUR in `.grid.four`, roughly 200px of text width at
   a typical desktop size. Unbroken, it runs past the callout's right edge.
   Opt-in rather than a change to `.ui`, so every short label stays atomic. */
.ui.wrap {
  white-space: normal;
}

/* ----------------------------------------------------------- site header -- */

header.site {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}

header.site .wrap {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 64px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 750;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--text);
  white-space: nowrap;
}

/* The itfanatic mark — the real logo since 2026-09-21.
 *
 * It REPLACED two offset squares drawn in pure CSS, whose comment read "drawn in
 * CSS so the logo costs no request and needs no file". That tradeoff is now paid
 * deliberately: one request, 4.7 KB over WebP.
 *
 * 🔴 34px IS A FLOOR, NOT A PREFERENCE. The artwork is a detailed illustration —
 * gear, rocket flame, circuit traces, a chip at the centre — and it was MEASURED
 * at 22px (the placeholder's size), 26px, 34px and 44px before this was written.
 * At 22px it renders as an unreadable purple blob, strictly worse than the
 * placeholder it replaces; 34px is the smallest size at which the gear and the
 * rocket are distinguishable. Shrinking this back to fit a tighter header
 * silently undoes the change. The 64px header has the room.
 *
 * NO THEME VARIANT IS NEEDED and none should be added: the source artwork carries
 * its own near-black backdrop (#161826), so the rounded box reads as an app icon
 * against both the light and the dark page background.
 *
 * Two background-image lines, and the ORDER IS LOAD-BEARING: a browser without
 * image-set() support ignores the second declaration and keeps the PNG from the
 * first. Do not collapse them into one.
 *
 * Self-hosted, same-origin, so /privacy's "no third-party resources" claim stays
 * true — the same reasoning that governs the favicons. */
.brand .mark {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: inline-block;
  flex: none;
  background-image: url("/logo-128.png");
  background-image: image-set(
    url("/logo-128.webp") type("image/webp"),
    url("/logo-128.png") type("image/png")
  );
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

header.site nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 22px;
}

header.site nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 500;
}

header.site nav a:hover {
  color: var(--text);
}

header.site nav a.btn {
  color: var(--accent-ink);
}

header.site nav a.btn:hover {
  color: var(--accent-ink);
}

@media (max-width: 720px) {
  header.site nav a.hide-sm {
    display: none;
  }
}

/* The payment-processor disclosure that sits under a Buy CTA.
   Added 2026-09-21 on owner request: a buyer should know the button leaves the
   site for Stripe BEFORE clicking, not after the page changes under them. It is
   also the GDPR Art. 13 processor point made where it is actually read, rather
   than only on /privacy.
   Constrained to the text measure so it does not run the full width of a hero. */
.checkout-note {
  max-width: 46ch;
  margin-top: 10px;
}

.actions + .checkout-note {
  margin-top: 12px;
}

/* ---------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 12px 22px;
  border-radius: 9px;
  text-decoration: none;
  font-weight: 650;
  font-size: 0.98rem;
  line-height: 1.2;
  border: 1px solid transparent;
  box-shadow: var(--shadow-sm);
  transition: background 0.15s ease, transform 0.15s ease;
}

.btn:hover {
  background: var(--accent-hover);
  transform: translateY(-1px);
}

.btn.sm {
  padding: 8px 15px;
  font-size: 0.9rem;
  border-radius: 7px;
}

.btn.lg {
  padding: 15px 30px;
  font-size: 1.06rem;
}

.btn.secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-strong);
}

.btn.secondary:hover {
  background: var(--bg-alt);
  border-color: var(--text-faint);
}

.btn .sub {
  font-weight: 500;
  opacity: 0.75;
  font-size: 0.86em;
}

.actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin: 26px 0 14px;
  align-items: center;
}

/* ---------------------------------------------------------- os headings -- */
/*
 * Platform mark beside a download card's title. INLINE SVG, never an <img> or
 * a webfont: /privacy, /datenschutz and /cookies all state that this site makes
 * zero external requests, and `legal.test.ts` fails the build on a third-party
 * subresource. An icon is not worth weakening that claim.
 *
 * `fill: currentColor` so the marks inherit the heading colour and follow the
 * light/dark palette for free — a hard-coded fill would look wrong in one theme.
 */
.os-head {
  display: flex;
  align-items: center;
  gap: 9px;
}

.os-head svg {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  fill: currentColor;
}

/* ------------------------------------------- callouts inside a download card -- */
/*
 * The shared callouts are sized for body prose: 22px margins, 15px text. Dropped
 * into a download card they crowd out the buttons they are meant to annotate, so
 * they are tightened HERE rather than globally — every other callout on the site
 * is in running text and correct as it is.
 *
 * Scoped to `.grid.four` so it cannot reach the cards on `/` or `/404`, which
 * share the `.card` class and are laid out completely differently.
 */
.grid.four .card .note,
.grid.four .card .warn,
.grid.four .card .tip {
  margin: 14px 0 0;
  padding: 11px 13px;
  font-size: 14px;
  line-height: 1.5;
}

.grid.four .card .callout-title {
  font-size: 12px;
}

/* ------------------------------------------- screenshot inside a callout -- */
/*
 * A small same-origin screenshot used to SHOW a control rather than describe it.
 *
 * The border is not decoration. These are grabs of a light-themed OS dialog, so
 * on the dark palette the image is a bright rectangle floating on a dark page;
 * a 1px border in the theme's own colour gives it an edge and stops it reading
 * as a rendering fault. width:100%/height:auto keeps it inside a narrow card,
 * and the intrinsic width/height on the <img> reserves the space so the buttons
 * below it do not jump when it loads.
 */
.dl-shot {
  display: block;
  width: 100%;
  height: auto;
  margin: 10px 0 0;
  border: 1px solid var(--border);
  border-radius: 6px;
}

/* ------------------------------------------------------- download lists -- */
/*
 * Stacked, full-width buttons inside a per-OS card. `.actions` is a wrapping
 * ROW, which is right for two or three choices side by side and wrong for a
 * list of nine artifacts: at card width the buttons wrapped into ragged pairs
 * and the reader could not scan one platform's options down a column.
 *
 * space-between puts the format on the left and the size hard right, so the
 * sizes line up as a column you can compare — the actual question being asked
 * here is "which of these do I want", and size is half the answer.
 */
.dl-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0 0;
}

.dl-group .btn {
  width: 100%;
  justify-content: space-between;
  text-align: left;
}

/* The size never wraps under the label, even at the narrowest card. */
.dl-group .btn .sub {
  white-space: nowrap;
}

/* Sub-heading inside a download card — macOS is the only one that needs it,
   because its two builds are separate downloads rather than two formats. */
.dl-arch {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 22px 0 0;
}

.dl-group + .dl-arch {
  margin-top: 24px;
}

/* ---------------------------------------------------------------- badges -- */

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

.badges li {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 14px;
}

.pill {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  padding: 4px 13px;
}

.pill.amber {
  color: var(--warning);
  background: var(--warning-bg);
  border-color: var(--warning-border);
}

.pill.green {
  color: var(--success);
  background: var(--success-bg);
  border-color: var(--success-border);
}

/* --------------------------------------------------------------- sections -- */

section {
  padding: 76px 0;
  border-top: 1px solid var(--border);
}

section.tint {
  background: var(--bg-alt);
}

section.flush {
  border-top: none;
}

.section-head {
  max-width: var(--prose-max);
  margin-bottom: 34px;
}

.section-head.center {
  text-align: center;
}

/* ------------------------------------------------------------------- hero -- */

.hero {
  padding: 72px 0 64px;
  border-top: none;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 56px;
  align-items: center;
}

.hero-copy {
  max-width: 620px;
}

.hero-note {
  font-size: 0.9rem;
  color: var(--text-faint);
  margin: 10px 0 0;
}

.hero-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-lg);
  background: var(--bg-alt);
}

@media (max-width: 940px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }
}

/* ------------------------------------------------------------------ cards -- */

.grid {
  display: grid;
  gap: 20px;
}

.grid.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/*
 * Four across, for the download cards: Windows, the two Macs, Linux. The Macs
 * are separate COLUMNS rather than two halves of one card because they are
 * separate downloads that do not substitute for each other — a reader picking
 * from a list should never have to notice a sub-heading to avoid taking the
 * wrong one.
 *
 * Drops to 2 at 1100px rather than 900px: four cards each holding stacked
 * full-width buttons run out of width sooner than four cards of prose.
 */
.grid.four {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1100px) {
  .grid.four {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .grid.three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .grid.two,
  .grid.three,
  .grid.four {
    grid-template-columns: minmax(0, 1fr);
  }
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px 26px;
  box-shadow: var(--shadow-sm);
}

.card > :first-child {
  margin-top: 0;
}

.card > :last-child {
  margin-bottom: 0;
}

.card p {
  color: var(--text-muted);
}

.card .icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
  font-size: 17px;
  margin-bottom: 14px;
}

/* A product card on the umbrella homepage. */
.product-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 34px;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 30px;
  box-shadow: var(--shadow);
}

.product-card img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow);
}

@media (max-width: 860px) {
  .product-card {
    grid-template-columns: minmax(0, 1fr);
    padding: 24px;
  }
}

/* The "nothing else here yet" placeholder, so the umbrella reads as
   deliberate rather than unfinished. */
.card.ghost {
  border-style: dashed;
  background: transparent;
  box-shadow: none;
  color: var(--text-faint);
}

/* ------------------------------------------------------------ price block -- */

.price-card {
  background: var(--surface);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius-lg);
  padding: 34px 36px;
  box-shadow: var(--shadow);
  max-width: 560px;
}

.price-card .pill {
  margin-bottom: 18px;
}

.price-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  margin: 4px 0 2px;
}

.price-now {
  font-size: clamp(2.8rem, 7vw, 3.6rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
}

.price-unit {
  font-size: 1rem;
  color: var(--text-muted);
  font-weight: 500;
}

.price-later {
  margin: 14px 0 0;
  color: var(--text-muted);
  font-size: 0.98rem;
}

.price-later strong {
  color: var(--text);
}

.price-card .actions {
  margin-bottom: 8px;
}

.price-card .btn {
  width: 100%;
}

/* The ways to pay: Stripe first, then PayPal (only while switched on), then the
   Microsoft Store and the Mac App Store — each a full-width button in the SAME style
   (owner, 2026-10-17), with its own one-line note. */
.price-card .paypal-option,
.price-card .store-option {
  margin-top: 16px;
}

/* The PayPal mark, inlined in the button (never an <img>: no third-party requests).
   One colour — the button's own text colour — so it reads on the accent background
   in light and dark mode alike. */
.paypal-mark {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  fill: currentColor;
}

.price-list {
  list-style: none;
  padding: 0;
  margin: 20px 0 0;
  border-top: 1px solid var(--border);
  padding-top: 18px;
}

.price-list li {
  position: relative;
  padding-left: 26px;
  margin: 9px 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

.price-list li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 0.62em;
  width: 10px;
  height: 5px;
  border-left: 2px solid var(--success);
  border-bottom: 2px solid var(--success);
  transform: rotate(-45deg);
}

.price-list li.no::before {
  transform: none;
  border: none;
  background: var(--text-faint);
  height: 2px;
  width: 10px;
  top: 0.75em;
}

/* ------------------------------------------------------------- comparison -- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

@media (max-width: 780px) {
  .split {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --------------------------------------------------------------- callouts -- */

.note,
.warn,
.tip,
.safe {
  margin: 22px 0;
  padding: 15px 19px;
  border-radius: 8px;
  border: 1px solid var(--border);
  border-left-width: 3px;
  background: var(--bg-alt);
  font-size: 15px;
}

.note > :first-child,
.warn > :first-child,
.tip > :first-child,
.safe > :first-child {
  margin-top: 0;
}

.note > :last-child,
.warn > :last-child,
.tip > :last-child,
.safe > :last-child {
  margin-bottom: 0;
}

.note {
  border-left-color: var(--accent);
}

.tip {
  border-left-color: var(--accent);
  background: var(--accent-soft);
}

.warn {
  border-left-color: var(--warning-border);
  background: var(--warning-bg);
}

.safe {
  border-left-color: var(--success-border);
  background: var(--success-bg);
}

.callout-title {
  display: block;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 4px;
}

.warn .callout-title {
  color: var(--warning);
}

.safe .callout-title {
  color: var(--success);
}

.note .callout-title,
.tip .callout-title {
  color: var(--accent);
}

/* ---------------------------------------------------------------- figures -- */

figure {
  margin: 30px 0;
}

figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow);
  background: var(--bg-alt);
}

figcaption {
  margin-top: 10px;
  font-size: 14px;
  color: var(--text-faint);
  line-height: 1.5;
}

/* ----------------------------------------------------------------- tables -- */

.scroll {
  overflow-x: auto;
  margin: 22px 0;
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 420px;
  font-size: 15px;
}

th,
td {
  text-align: left;
  vertical-align: top;
  padding: 10px 16px 10px 0;
  border-bottom: 1px solid var(--border);
}

th {
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 700;
  border-bottom-color: var(--border-strong);
}

td:first-child {
  font-weight: 600;
  padding-right: 22px;
}

/* -------------------------------------------------------------- step list -- */

ol.steps {
  counter-reset: step;
  list-style: none;
  padding-left: 0;
}

ol.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: 46px;
  margin: 20px 0;
}

ol.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 1px;
  width: 29px;
  height: 29px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* -------------------------------------------------------------------- faq -- */

.faq {
  max-width: var(--prose-max);
}

.faq details {
  border-bottom: 1px solid var(--border);
  padding: 4px 0;
}

.faq summary {
  cursor: pointer;
  font-weight: 650;
  padding: 15px 32px 15px 0;
  position: relative;
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 22px;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--text-faint);
  border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}

.faq details[open] summary::after {
  transform: rotate(-135deg);
  top: 26px;
}

.faq details > *:not(summary) {
  color: var(--text-muted);
  margin-top: 0;
}

.faq details > *:last-child {
  margin-bottom: 18px;
}

/* --------------------------------------------------------------- cta band -- */

.cta {
  background: var(--accent-soft);
  border-top: 1px solid var(--accent-border);
  border-bottom: 1px solid var(--accent-border);
  text-align: center;
  padding: 66px 0;
}

.cta h2 {
  margin-bottom: 8px;
}

.cta .lede {
  margin-left: auto;
  margin-right: auto;
  max-width: 560px;
}

.cta .actions {
  justify-content: center;
}

/* ----------------------------------------------------------------- footer -- */

footer.site {
  border-top: 1px solid var(--border);
  background: var(--bg-alt);
  padding: 40px 0 52px;
  font-size: 0.9rem;
  color: var(--text-faint);
}

footer.site .cols {
  display: flex;
  flex-wrap: wrap;
  gap: 28px 56px;
  align-items: flex-start;
  justify-content: space-between;
}

footer.site nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
}

footer.site a {
  color: var(--text-muted);
  text-decoration: none;
}

footer.site a:hover {
  color: var(--text);
  text-decoration: underline;
}

footer.site .fine {
  margin: 22px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  max-width: var(--prose-max);
  font-size: 0.85rem;
  line-height: 1.6;
}

/* ------------------------------------------------------------ legal pages -- */

/* A single-column reading layout for /privacy, /terms and /refunds. Narrower
   measure than the marketing pages, and h2s get a rule above them so a long
   policy is scannable. */
.doc {
  padding: 56px 0 80px;
}

.doc .prose h2 {
  font-size: 1.42rem;
  margin: 56px 0 6px;
  padding-top: 26px;
  border-top: 1px solid var(--border);
}

.doc .prose h2:first-of-type {
  border-top: none;
  padding-top: 0;
  margin-top: 40px;
}

.doc .prose h3 {
  margin: 32px 0 4px;
}

.doc .prose .card h3 {
  margin-top: 0;
}

/* ------------------------------------------------------------------- misc -- */

.stack-sm > * + * {
  margin-top: 8px;
}

.nowrap {
  white-space: nowrap;
}

@media (max-width: 640px) {
  .wrap {
    padding: 0 20px;
  }

  section {
    padding: 56px 0;
  }

  .hero {
    padding: 48px 0 44px;
  }

  .price-card {
    padding: 26px 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .btn,
  .faq summary::after {
    transition: none;
  }

  .btn:hover {
    transform: none;
  }
}

/*
 * Video guide (/image-organizer/videos). Each video is our own poster inside a
 * button; /video.js swaps in the YouTube player only when it is pressed, so the
 * button and the iframe share one 16:9 box and nothing jumps.
 */
.video {
  margin: 0;
}

.video-featured {
  max-width: 960px;
  margin: 0 auto 48px;
}

.video-play {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: #0b1120;
  cursor: pointer;
}

.video-play img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-play-icon {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.72);
  transition: background 0.15s ease;
}

.video-play-icon::after {
  content: "";
  position: absolute;
  left: 25px;
  top: 20px;
  border-style: solid;
  border-width: 12px 0 12px 20px;
  border-color: transparent transparent transparent #fff;
}

.video-play:hover .video-play-icon,
.video-play:focus-visible .video-play-icon {
  background: var(--accent);
}

.video-play:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.video-time {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 2px 7px;
  border-radius: 4px;
  background: rgba(15, 23, 42, 0.82);
  color: #fff;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.video-frame {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--radius);
  background: #0b1120;
}

.video figcaption {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 12px;
}

.video-grid {
  row-gap: 36px;
}

@media (prefers-reduced-motion: reduce) {
  .video-play-icon {
    transition: none;
  }
}

/* The PayPal option ships hidden and is revealed only by the Worker while the
   PADDLE_CHECKOUT switch is on (src/checkout/paypal.ts). !important so that no
   display rule on this element can ever show it with the switch off. */
[data-paddle-checkout][hidden] {
  display: none !important;
}
