/* ============================================================
   Trawler brand layer.

   tokens.css carries the WinUI 3 / Fluent structure -- spacing,
   radii, neutral text and surfaces, and the dark theme. This file
   sits on top of it and supplies the brand.

   ⛔ ONE ACCENT, AND IT COMES FROM THE LOGO. Every colour below is
   a stop on the logo mark's own gradient. An earlier pass drew from
   a seven-colour palette sheet and read as a rainbow: colour marks
   the one thing that matters on a screen, so a page where
   everything is coloured has nothing emphasised. Do not reintroduce
   extra hues "for variety" -- if a new element needs separating,
   move along this gradient, do not step off it.

   ⛔ This file is SERVED VERBATIM to every visitor. Keep the
   rationale for these values in website.md, which is not published
   -- a comment here is a public statement. See website.md §2a.
   ============================================================ */

/* Self-hosted, deliberately. A fonts.googleapis.com link sends every
   visitor's IP to Google, which does not sit well beside a privacy
   page claiming no third-party tracking. SIL OFL 1.1 -- licence in
   src/fonts/Sora-OFL.txt, which ships with the site. */
@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/sora-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/sora-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ⭐ The accent is taken from the LOGO, not from a palette sheet. The mark ships
   in the app and on the Store listing, so it is the identity everything else
   has to agree with -- a button in a different blue from the logo reads as a
   mistake. These four are lifted from
   design/trawler-logo-v6-gradient-waterline.svg. */
:root {
  --brand:      #1E7FD9;   /* the bars on the documents in the mark */
  --brand-hover:#1668B8;
  --brand-deep: #0E4287;   /* the keel: only ever the far end of a gradient */
  --brand-lift: #5DB3F7;   /* the waterline stripe: highlights on dark only */
  --brand-ink:  #0B1729;   /* a navy from the same family, not a neutral black */
  --brand-tint: rgba(30, 127, 217, 0.09);
  --brand-edge: rgba(30, 127, 217, 0.24);
  --brand-font: 'Sora', 'Segoe UI Variable Display', 'Segoe UI', system-ui, sans-serif;
  --shell: 1120px;
  --page-bg: #FFFFFF;
  --header-bg: rgba(255, 255, 255, 0.78);
}
[data-theme="dark"] {
  --brand-tint: rgba(93, 179, 247, 0.16);
  --brand-edge: rgba(93, 179, 247, 0.28);
  --page-bg: #14171C;
  --header-bg: rgba(20, 23, 28, 0.78);
}

/* tokens.css already sets a body background (--solid-background-base, #F3F3F3
   light / #202020 dark). This overrides it deliberately: a marketing page wants
   pure white behind bordered cards, not the app shell's grey. Keep both themes
   defined here -- declaring only the light one would leave the dark page on the
   Fluent grey while everything around it moved. */
body {
  font-family: var(--brand-font);
  background: var(--page-bg);
  color: var(--text-primary);
}
h1, h2, h3 { font-family: var(--brand-font); letter-spacing: -0.022em; }

/* ---- sticky header ----------------------------------------- */

/* The bar spans the viewport so the blur and border run edge to edge, but its
   CONTENTS sit on the same 1400px shell as the hero, so the mark lines up with the
   headline below it and the theme toggle lines up with the right edge of the shot. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: block;
  padding: var(--space-3) var(--space-6);
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border-secondary);
}
.header-inner {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.logo {
  font-family: var(--brand-font);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
}
.logo img { width: 26px; height: 26px; margin-right: 10px; display: block; }
/* tokens.css underlines every <a> on hover; a wordmark is not a link to underline. */
.logo, .logo:hover { text-decoration: none; }
.site-nav { display: flex; gap: var(--space-5); align-items: center; }
.site-nav a { font-size: 14px; font-weight: 500; color: var(--text-secondary); }
.site-nav a:hover { color: var(--text-primary); }
.site-nav a.nav-cta {
  background: var(--brand);
  color: #fff;
  padding: 9px 20px;
  border-radius: 8px;
  font-weight: 600;
}
.site-nav a.nav-cta:hover { background: var(--brand-hover); color: #fff; }

/* ---- section rhythm ---------------------------------------- */

.section { max-width: var(--shell); margin: 0 auto; padding: var(--space-14) var(--space-6); }
.section-head { max-width: 660px; margin-bottom: var(--space-10); }
.section-head .kicker {
  display: block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: var(--space-3);
}
/* ⚠ `balance` is what stops a heading dropping ONE word onto its own line ("...you
   care / about"). It is a global fix rather than a per-heading one because the fault
   is a function of the string length against the column, so any future heading has
   it too. `pretty` does the same for the paragraph's last line. Both degrade to
   normal wrapping where unsupported -- nothing depends on them. */
.section-head h2 { font-size: clamp(26px, 3.2vw, 38px); line-height: 1.15; margin-bottom: var(--space-4); text-wrap: balance; }
.section-head p { text-wrap: pretty; }
.section-head h2 em { font-style: normal; color: var(--brand); }
/* A two-sentence heading must break BETWEEN the sentences, never inside one.
   Each phrase is its own inline-block, so it wraps as a unit. */
.h2-phrases > span, .h2-phrases > em { display: inline-block; }
.section-head p { color: var(--text-secondary); font-size: 17px; line-height: 1.65; }
.section-head--center { max-width: 640px; margin-left: auto; margin-right: auto; text-align: center; }

/* A section that answers a yes/no question does not get a headline the size of one that
   makes an argument. Used by the file-types strip, which is reference material: it keeps
   its <h2> for document structure and search, and gives up the visual rank. ⚠ The size
   here must stay BELOW the clamp's floor above (26px) at every viewport, or the modifier
   does nothing on small screens and quietly stops being a demotion. */
.section-head--compact { margin-bottom: var(--space-6); }
.section-head--compact h2 { font-size: clamp(20px, 2vw, 23px); }
.section-head--compact p { font-size: 15px; }

/* ---- hero: dark, copy left, shot right ----------------------

   ⭐ The shot cannot show a 2560px desktop capture legibly at any column width,
   so it LINKS to the full-resolution file instead (`.hero-shot-open`). That is
   better than a lightbox, which would be capped by the viewport, and it needs no
   JavaScript. The column is pushed as wide as the layout allows and the grid is
   wider than the page shell for the same reason. */

.hero-dark {
  background:
    radial-gradient(ellipse 60% 80% at 12% 0%, rgba(30, 127, 217, 0.22), transparent 62%),
    radial-gradient(ellipse 55% 65% at 92% 12%, rgba(93, 179, 247, 0.14), transparent 60%),
    var(--brand-ink);
  color: #fff;
  padding: clamp(48px, 6vw, 88px) var(--space-6) clamp(56px, 7vw, 96px);
  overflow: hidden;
}
.hero-grid {
  max-width: 1400px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 40fr) minmax(0, 60fr);
  gap: clamp(28px, 3.5vw, 56px);
  align-items: center;
}
@media (max-width: 1020px) { .hero-grid { grid-template-columns: 1fr; } }

.hero-pill {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #9FD3FF;
  background: rgba(30, 127, 217, 0.20);
  border: 1px solid rgba(93, 179, 247, 0.34);
  padding: 6px 14px;
  border-radius: 999px;
  margin-bottom: var(--space-5);
}
/* Sized for the 40% column, not the viewport: 5.4vw overflowed it badly. */
.hero-copy h1 {
  font-size: clamp(34px, 3.7vw, 52px);
  line-height: 1.05;
  font-weight: 700;
  color: #fff;
  margin-bottom: var(--space-5);
}
.hero-copy h1 em { font-style: normal; color: #5DB3F7; }
.hero-lede {
  font-size: clamp(16px, 1.2vw, 18px);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.74);
  margin: 0 0 var(--space-8);
}
.hero-btnrow {
  display: flex;
  gap: var(--space-3);
  align-items: stretch;
  justify-content: flex-start;
  flex-wrap: wrap;
  margin-bottom: var(--space-8);
}
.cta-band .hero-btnrow { justify-content: center; }
.trust { justify-content: flex-start; }


/* ⛔ ALWAYS-DARK SURFACES MUST NOT USE THEME TOKENS.
   `.hero-dark` and `.cta-band` are dark in BOTH themes, but the button classes
   above take their text from --text-primary / --text-tertiary, which follow the
   theme. In light mode those resolve to near-black, so the buttons rendered dark
   text on a dark panel -- unreadable, and only in one of the two themes, which is
   why it survived review. Any component placed on a fixed-colour surface needs an
   explicit colour here; do not rely on the token. */
.hero-dark .btn-secondary {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.06);
}
.hero-dark .btn-secondary:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.12);
}
.hero-dark .btn-primary[aria-disabled="true"],
.cta-band .btn-primary[aria-disabled="true"] {
  color: rgba(255, 255, 255, 0.62);
  border-color: rgba(255, 255, 255, 0.26);
  background: transparent;
}
/* ⛔ <small> DOES NOT INHERIT ITS COLOUR. tokens.css carries a bare element
   selector -- `.type-caption, small { color: var(--text-secondary) }` -- so every
   <small> gets the THEME's secondary text colour regardless of what its parent is
   set to. On the dark hero that rendered the button sub-labels near-black in light
   mode while the <strong> above them stayed white, which is exactly how it looked:
   half the button legible, half not.
   `color: inherit` puts them back under their parent, and the opacity does the
   dimming. Anything else placed on a dark surface needs the same check -- read
   tokens.css for bare element selectors before assuming inheritance. */
.hero-dark small,
.cta-band small { color: inherit; }
.hero-dark .btn-stack small,
.cta-band .btn-stack small { opacity: 0.72; }

.trust { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-6); }
.trust li {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.trust strong { display: block; font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.92); }
.trust-glyph { color: #4ED8B0; font-size: 9px; line-height: 1; margin-bottom: 4px; }

.hero-shot { margin: 0; }
.hero-shot-open { display: block; position: relative; }
.hero-shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.50);
}
/* The affordance has to be visible without a hover, because on a touch screen
   there is no hover to discover it with. */
.hero-shot-hint {
  position: absolute;
  right: 12px;
  bottom: 12px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  background: rgba(11, 23, 41, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 7px;
  padding: 6px 12px;
  backdrop-filter: blur(6px);
}
.hero-shot-open:hover .hero-shot-hint { background: var(--brand); border-color: var(--brand); }
.hero-shot-open:hover img { border-color: rgba(93, 179, 247, 0.55); }
.hero-shot figcaption {
  margin-top: var(--space-3);
  font-size: 13px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.52);
}

/* On a wide screen let the shot run past the right edge: it reads as a window
   into the app rather than a picture pasted on the page, and buys real pixels.
   Safe only because .hero-dark clips -- without that this is a horizontal
   scrollbar on every page. */
@media (min-width: 1500px) {
  .hero-shot { margin-right: clamp(-120px, -5vw, -48px); }
  .hero-shot img { width: calc(100% + 5vw); max-width: none; }
}

.btn-primary {
  display: inline-block;
  background: var(--brand);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 14px 28px;
  font-size: 15px;
  font-weight: 600;
  box-shadow: 0 6px 18px rgba(30, 127, 217, 0.28);
}
.btn-primary:hover { background: var(--brand-hover); color: #fff; }
.btn-primary[aria-disabled="true"] {
  background: transparent;
  color: var(--text-tertiary);
  border: 1px dashed var(--border-secondary);
  box-shadow: none;
  cursor: default;
}
.btn-secondary {
  display: inline-block;
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-secondary);
  border-radius: 10px;
  padding: 14px 28px;
  font-size: 15px;
  font-weight: 600;
}
.btn-secondary:hover { border-color: var(--brand); color: var(--brand); }

/* ⛔ .btn-stack MUST STAY BELOW .btn-primary AND .btn-secondary.
   It overrides `display`, and all three are single-class selectors, so the
   cascade is decided purely by source order. It was written above them once:
   `display: inline-block` won, `flex-direction: column` became meaningless, and
   the two lines of every hero button rendered on top of each other. The page
   still built, every test passed, and it was wrong only where a human looked.
   Pinned by `the two-line button rule comes after the button rules it overrides`. */
.btn-stack { display: inline-flex; flex-direction: column; gap: 2px; text-align: left; padding: 13px 26px; }
.btn-stack strong { font-size: 16px; font-weight: 600; }
.btn-stack small { font-size: 12.5px; opacity: 0.8; font-weight: 400; line-height: 1.35; }

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

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--space-4); }
.card { background: var(--card-background-default); border: 1px solid var(--border-secondary); border-radius: 14px; padding: var(--space-5); }
.card h3 { font-size: 16px; font-weight: 600; margin-bottom: var(--space-2); }
.card p { color: var(--text-secondary); font-size: 14px; line-height: 1.6; }

/* The single accent moment: the feature the product is sold on. */
.card-lead { border-color: var(--brand-edge); background: var(--brand-tint); }

.card-link { display: inline-block; margin-top: var(--space-3); font-size: 13px; font-weight: 600; color: var(--brand); }
.card-link:hover { color: var(--brand-hover); }

/* A card that lifts on hover reads as a thing you can act on -- each one leads
   somewhere. ⚠ Guarded: `prefers-reduced-motion` is a real accessibility setting,
   and a transform that ignores it is the exact class of motion it exists to stop. */
.card { transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease; }
.card:hover {
  transform: translateY(-3px);
  border-color: var(--brand-edge);
  box-shadow: 0 12px 24px -14px rgba(11, 23, 41, 0.45);
}
[data-theme="dark"] .card:hover { box-shadow: 0 12px 26px -14px rgba(0, 0, 0, 0.7); }
@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
  .card:hover { transform: none; }
}

/* Icon tiles.
   ⛔ The glyphs here were Unicode TEXT characters (A3 ¸E ¶A B6) and that is
   why they never matched each other: Sora contains none of them, so each one fell
   through to a DIFFERENT system fallback font and arrived at a different weight,
   optical size and baseline. No font-size fixes that -- there is no single typeface
   drawing that set. They are inline SVG now, one hand-drawn family at one stroke
   width, which is also the only way a mark here can carry depth: a text glyph accepts
   `color` and nothing else.

   The tint is a PALE step along the logo's own gradient -- light deck to deep keel.
   Four steps is enough to separate four categories and nowhere near a rainbow. */
.tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  margin-bottom: var(--space-3);
  /* Defaults, so a .tile with no modifier is still a complete rule. */
  --tile-lift: rgba(93, 179, 247, 0.20);
  --tile-base: rgba(30, 127, 217, 0.10);
  background-image: linear-gradient(155deg, var(--tile-lift), var(--tile-base));
  /* Three layers, in order: a top-edge highlight so the tile catches light, a tight
     contact shadow, and a wide soft one for lift. The wide layer is the one doing the
     work -- without it the tile reads as a coloured rectangle rather than an object. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    0 1px 1px rgba(11, 23, 41, 0.05),
    0 8px 16px -10px rgba(11, 23, 41, 0.45);
  color: var(--brand);
}
.tile svg { display: block; width: 23px; height: 23px; }

.tile-a { --tile-lift: rgba(93, 179, 247, 0.26); --tile-base: rgba(93, 179, 247, 0.08); color: #2C7FD0; }
.tile-b { --tile-lift: rgba(30, 127, 217, 0.20); --tile-base: rgba(30, 127, 217, 0.06); color: #1E7FD9; }
.tile-c { --tile-lift: rgba(14, 66, 135, 0.18);  --tile-base: rgba(14, 66, 135, 0.05); color: #0E4287; }
.tile-d { --tile-lift: rgba(30, 127, 217, 0.28); --tile-base: rgba(30, 127, 217, 0.10); color: var(--brand); }

/* Dark theme: a white top highlight at 55% reads as a scratch on a dark tile, and the
   shadow has to deepen or the tile floats on nothing. Both are re-declared, not tweaked. */
[data-theme="dark"] .tile {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 1px 1px rgba(0, 0, 0, 0.30),
    0 8px 18px -10px rgba(0, 0, 0, 0.65);
}
[data-theme="dark"] .tile-a { --tile-lift: rgba(93, 179, 247, 0.26); --tile-base: rgba(93, 179, 247, 0.08); color: #8FCEFF; }
[data-theme="dark"] .tile-b { --tile-lift: rgba(30, 127, 217, 0.34); --tile-base: rgba(30, 127, 217, 0.12); color: #5DB3F7; }
[data-theme="dark"] .tile-c { --tile-lift: rgba(93, 179, 247, 0.18); --tile-base: rgba(93, 179, 247, 0.06); color: #7FB6E8; }
[data-theme="dark"] .tile-d { --tile-lift: rgba(30, 127, 217, 0.40); --tile-base: rgba(30, 127, 217, 0.14); color: #9FD3FF; }

/* ---- three steps -------------------------------------------

   ⛔ The problem here was never decoration. Three text columns with a numbered
   disc on top do not read as a SEQUENCE -- nothing in the layout says one follows
   another, so the eye takes them as three unrelated facts and the "three steps"
   promise in the heading is contradicted by the thing underneath it.

   Two fixes, both structural rather than cosmetic:
   1. A connector hairline running from each badge to the next, on the badge's own
      centre line. Drawn on the LI and suppressed on the last one -- there is nothing
      after step 3 to point at, and a line trailing off the end would say there is.
   2. The badges DEEPEN 1 -> 3 along the logo's own gradient, light deck to keel, so
      the colour itself carries progress. Still one hue; this is not a second accent. */

/* ⭐ The SECOND rebuild of this section, and the reason is worth keeping.

   Version one was three columns with numbered discs, which did not read as a sequence.
   That was fixed with a connector hairline -- and the section was still the weakest on
   the page, because the fault underneath was never decoration at all: Find / Decide /
   Process is the HERO RESTATED ("Find the copies. Compare them. Keep the right one."),
   400px lower, in a box. It was the one section that added nothing.

   It is now the only place below the hero where the product appears. Measured before
   the change: five sections, twenty-one items, eighteen icons and ZERO screenshots on a
   page whose entire pitch is that you can SEE the difference. Everything after the hero
   asked the reader to take it on trust, and this sat in the middle of it describing what
   a screenshot would have shown.

   So the three steps now carry three shots, and each one has to prove its own sentence
   rather than illustrate it: seven versions of one photograph that share no bytes; the
   comparison panel disagreeing on four rows out of seven; and the action list with
   archive pre-selected and permanent deletion named in red. If a shot is ever replaced
   with one that does not carry its claim, the section is back to being decoration.

   ⛔ ALWAYS-DARK SURFACE. Every colour below is explicit and there is no [data-theme]
   variant, because this band is dark in BOTH themes. An inherited theme token here
   renders near-black on navy in exactly one theme -- which this stylesheet has already
   shipped twice, once for <small> and once for the hero buttons. The rule is not "add a
   dark override", it is "never let a colour arrive here by inheritance".

   It also does the page's rhythm a favour: white, white, DARK, white, tinted, white,
   dark-CTA. Before this the whole middle of the page was an unbroken run of white. */
.steps-band {
  background:
    radial-gradient(ellipse 70% 60% at 50% 0%, rgba(30, 127, 217, 0.20), transparent 65%),
    var(--brand-ink);
  color: #fff;
  padding: clamp(56px, 6vw, 92px) var(--space-6) clamp(60px, 7vw, 100px);
}
.steps-band-inner { max-width: var(--shell); margin: 0 auto; }

/* The heading block is inside a dark band, so every one of its parts needs saying. */
.steps-band .section-head { margin-bottom: var(--space-10); }
.steps-band .section-head h2 { color: #fff; }
.steps-band .section-head h2 em { color: #7FC1FA; }
.steps-band .section-head p { color: rgba(255, 255, 255, 0.72); }
.steps-band .kicker { color: #7FC1FA; }

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(48px, 6vw, 84px);
}

/* ⛔ No connector hairline any more, and its absence is deliberate rather than lost in
   the rewrite. It existed to make three side-by-side columns read as an order. Stacked
   down the page, 1 then 2 then 3 IS the order -- a line would be re-stating what the
   layout already says. */
.step-say { max-width: 640px; margin: 0 auto var(--space-6); text-align: center; }
.steps h3 { font-size: 19px; font-weight: 600; margin: var(--space-3) 0 var(--space-2); color: #fff; }
.steps p { color: rgba(255, 255, 255, 0.72); font-size: 15px; line-height: 1.7; }

/* The shot is the evidence, so it gets the width and the caption gets the middle.
   `height: auto` is load-bearing next to the width/height attributes on the <img>: those
   exist to reserve the right space before the file arrives (no layout shift), and without
   it the intrinsic height would fight the fluid width. */
.step-shot { margin: 0; }
.step-shot img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 960px;
  margin: 0 auto;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.85);
}
/* The process shot is a centred dialog rather than a full workspace, so it is cropped
   tight and shown smaller. Scaling it to the other two would leave its words -- "Default
   / recoverable", "not recoverable" -- too small to read, and those words ARE the claim. */
.step-shot--narrow img { max-width: 700px; }

.step-n {
  --step-lift: #5DB3F7;
  --step-base: #1E7FD9;
  display: inline-grid;
  place-items: center;
  position: relative;
  z-index: 1;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background-image: linear-gradient(160deg, var(--step-lift), var(--step-base));
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 1px 2px rgba(11, 23, 41, 0.18),
    0 8px 16px -8px rgba(30, 127, 217, 0.55);
}
.steps li:nth-child(1) .step-n { --step-lift: #7CC4FA; --step-base: #2E8CE0; }
.steps li:nth-child(2) .step-n { --step-lift: #5DB3F7; --step-base: #1668B8; }
.steps li:nth-child(3) .step-n { --step-lift: #3E97E4; --step-base: #0E4287; }
[data-theme="dark"] .step-n {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 1px 2px rgba(0, 0, 0, 0.35),
    0 8px 18px -8px rgba(0, 0, 0, 0.6);
}

/* ---- supported types --------------------------------------- */

/* ⛔ This was five equal columns of comma-separated text, and all three faults were
   in that one decision. It read FLAT because a comma list has no unit the eye can
   count. It could not GROW -- the document list is about to roughly double, and a
   long sentence of extensions is worse the more formats we support, which is exactly
   backwards for something that is meant to be a selling point. And "Everything else"
   is not a format list at all, so putting it in an identical fifth column claimed a
   parallel that isn't there.

   Rows with chips instead: one line per matcher, each format its own countable token,
   wrapping naturally however long the list gets. The catch-all is demoted to a closing
   line, because it is a different kind of claim. */
/* ONE panel with four rows, not four panels.

   This is reference material sitting in a persuasion slot: it answers "do you handle my
   stuff?", which is a yes/no, and it was charging a full section's worth of attention for
   it -- own kicker, full-size heading, four bordered cards, a closing line. Four card
   borders also made four separate things to look at, when the answer is one thing.

   Collapsed to a single bordered panel with hairline-separated rows: three borders and a
   chunk of padding gone, the same information, and the eye reads it as a footnote to the
   four matchers above rather than as a fifth claim. */
.types {
  list-style: none;
  margin: 0;
  padding: 0 var(--space-5);
  display: grid;
  border: 1px solid var(--border-secondary);
  border-radius: 14px;
  background: var(--card-background-default);
  max-width: 780px;
  margin-inline: auto;
}
.types > li {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: var(--space-4);
  align-items: start;
  padding: var(--space-4) 0;
}
.types > li + li { border-top: 1px solid var(--border-secondary); }
/* The tiles are the card icons re-used at a smaller size -- a deliberate callback, so
   the reader recognises the four categories rather than reading four new labels. */
.types .tile { width: 32px; height: 32px; border-radius: 10px; margin-bottom: 0; }
.types .tile svg { width: 17px; height: 17px; }
.types strong { display: block; font-size: 15px; font-weight: 600; margin-bottom: var(--space-2); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 4px 9px;
  border-radius: 7px;
  background: var(--brand-tint);
  border: 1px solid var(--brand-edge);
  color: var(--brand-deep);
}
/* "camera RAW" / "and more" are not formats, so they must not look like one -- an
   outlined chip reads as an aside rather than as another extension. */
.chip-more { background: transparent; border-color: var(--border-secondary); color: var(--text-secondary); font-weight: 500; }
/* --brand-deep is the keel navy: legible on a pale tint, invisible on a dark one. */
[data-theme="dark"] .chip { color: #BFDDFB; }

.types-more {
  margin-top: var(--space-4);
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1.7;
  text-align: center;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}

/* ---- also included -----------------------------------------

   This was one grey paragraph under a hairline, and its problem was that it read as
   an UNFINISHED section rather than as a deliberate aside. The positioning still
   holds -- exact duplicates are a by-product here, not the pitch -- so this must not
   turn into a fifth set of category cards competing with the four above it. Hence a
   different treatment entirely: a tinted full-bleed band, a LEFT-aligned head (every
   other section on the page is centred, and four centred heads in a row is the
   monotony this breaks), and compact icon rows rather than cards.

   ⚠ Every claim in here was checked against the code before it was written, not
   against CLAUDE.md: archive-as-default is `ProcessViewModel.Disposition`, and the
   link/restore claims are the `trawler_link_in_place` / `trawler_restore_moves` /
   `trawler_open_archive` exports. A landing page is a promise the product has to keep
   on the user's own files. */

.extras {
  --extras-tint-top: rgba(93, 179, 247, 0.09);
  --extras-tint-bottom: rgba(30, 127, 217, 0.02);
  background-color: var(--subtle-secondary);
  background-image: linear-gradient(180deg, var(--extras-tint-top), var(--extras-tint-bottom));
  border-top: 1px solid var(--border-secondary);
  border-bottom: 1px solid var(--border-secondary);
  padding: var(--space-14) 0;
}
[data-theme="dark"] .extras {
  --extras-tint-top: rgba(93, 179, 247, 0.06);
  --extras-tint-bottom: rgba(11, 23, 41, 0.25);
}
.extras-inner { max-width: var(--shell); margin: 0 auto; padding: 0 var(--space-6); }

.extras-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-6) var(--space-8);
}
.extras-grid li { display: grid; grid-template-columns: 34px 1fr; gap: var(--space-4); align-items: start; }
.extras-grid strong { display: block; font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.extras-grid span:not(.xicon) { display: block; color: var(--text-secondary); font-size: 14px; line-height: 1.65; }

/* Deliberately flatter than the category tiles: a ring rather than the filled
   gradient, so the eye reads these as supporting detail and not as four more
   headline features. Same icon family, one step down in emphasis. */
.xicon {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--card-background-default);
  border: 1px solid var(--brand-edge);
  color: var(--brand);
}
.xicon svg { width: 19px; height: 19px; display: block; }

.extras code {
  font-size: 0.92em;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--brand-tint);
  color: var(--brand-deep);
}
[data-theme="dark"] .extras code { color: #BFDDFB; }

/* ---- closing call to action -------------------------------- */

/* ---- safe to change your mind ------------------------------

   The last section before the CTA, and that placement is the whole argument. This
   answers the objection every visitor to a file-DELETING product arrives with, and
   it has to land after they believe the product works, not before -- safety copy in
   the hero primes the fear it answers, telling someone who was not yet worried that
   there is something to worry about.

   ⛔ The candid note at the end stays. Archiving and moving restore in-app, recycling
   is Windows' bin, DELETING IS PERMANENT. A page implying universal undo betrays the
   first user who hits a permanent delete, and naming the limit is what makes the rest
   of the section believable -- the honesty is the trust signal, not a caveat on it.

   Visually plain on purpose: the band above it is tinted and the CTA below is a dark
   gradient, so an open, centred, untinted section between them reads as a breath
   rather than a third panel. */

.safety { max-width: var(--shell); margin: 0 auto; padding: var(--space-20) var(--space-6) 0; }
/* Narrower than the band above it (900px -> 780px). A measurably shorter line length is
   the second half of the shape change: this section should feel like it is speaking
   more quietly than the capability list, not just wearing a different background. */
.safety-inner { max-width: 780px; margin: 0 auto; }

.safety-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-5) var(--space-8);
}
/* NO ICONS HERE, deliberately, and this is the whole point of the treatment.

   Zoomed out to the whole page, this section and "Also included" above it read as ONE
   ten-item list: both were two-column grids of ringed-icon + bold title + paragraph,
   differing only in background tint. Two sections making completely different KINDS of
   claim -- here is what else it does, versus here is why it is safe -- looked identical,
   so the page said everything in one voice.

   The fix is shape, not decoration. Dropping the icon column leaves a rule-topped
   statement list, which reads as an assurance rather than as more features, and costs no
   height. ⛔ Do not "restore" the icons for consistency with the band above: being
   consistent with it is the defect. */
.safety-grid li {
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-secondary);
}
.safety-grid strong { display: block; font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.safety-grid span { display: block; color: var(--text-secondary); font-size: 14px; line-height: 1.65; }

.safety-note {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border-secondary);
  color: var(--text-secondary);
  font-size: 13.5px;
  line-height: 1.75;
  text-align: center;
  max-width: 660px;
  margin-left: auto;
  margin-right: auto;
  text-wrap: pretty;
}

.cta-band {
  max-width: var(--shell);
  /* ⚠ Top margin is load-bearing, not taste. Every `.section` carries its own
     vertical padding, so the CTA inherited a gap from whatever sat above it -- and
     the "Also included" band ends in a hard border, giving it ZERO. The band was
     butted straight against that rule. Spacing that arrives by inheritance breaks
     the moment the section above changes shape; this one is declared. */
  margin: var(--space-20) auto var(--space-14);
  padding: var(--space-14) var(--space-6);
  border-radius: 18px;
  text-align: center;
  background: linear-gradient(135deg, var(--brand), var(--brand-deep));
  color: #fff;
}
.cta-band h2 { font-size: clamp(24px, 3vw, 34px); margin-bottom: var(--space-3); color: #fff; }
.cta-band p { color: rgba(255, 255, 255, 0.82); margin-bottom: var(--space-6); }
.cta-band .btn-secondary { background: #fff; color: var(--brand-ink); border-color: #fff; }

/* The price-model line. It sits under the buttons rather than above them because it
   answers an objection the button raises ("what does this actually cost me?"), and an
   objection answered before it forms reads as a defence.

   ⛔ ALWAYS-DARK SURFACE -- every colour here is explicit. `.cta-band p` already sets a
   white-alpha colour, but this rule needs its own: a bare `a` and a bare `strong` both
   take colour from elsewhere, and on a surface that is dark in BOTH themes an inherited
   theme token renders near-black in exactly one of them. That is the bug this file has
   already been bitten by twice (see the <small> note above).

   ⚠ Wording is from `docs/manual/free-and-pro.md`, which is the product's own statement:
   free finds everything and stops where files would change; the full version is a
   one-time Store unlock with no subscription, no trial clock and no expiry. Deliberately
   no PRICE -- there isn't one yet, and a number here would be the first thing to rot. */
.cta-note {
  margin: var(--space-6) auto 0;
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  max-width: 60ch;
  font-size: 13.5px;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.78);
  text-wrap: pretty;
}
.cta-note strong { color: #fff; font-weight: 600; }
.cta-note a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.cta-note a:hover { color: #fff; opacity: 0.85; }
.cta-band .btn-secondary:hover { color: var(--brand-ink); border-color: #fff; opacity: 0.92; }

/* ---- guide chrome ------------------------------------------ */

.learning-layout { max-width: var(--shell); margin: 0 auto; padding: var(--space-10) var(--space-6); }
.learning-nav a[aria-current="page"] { background: var(--brand-tint); color: var(--brand); }
.learning-nav-home { color: var(--brand); }
.learning-body h1 { font-size: clamp(26px, 4vw, 34px); line-height: 1.15; }
.learning-body a, .legal a { color: var(--brand); }
.learning-body blockquote { border-left-color: var(--brand); }

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

   ⚠ A footer should be sized by what EXISTS, not by what a footer usually looks
   like. Every link here resolves to a real page today -- `internal links all resolve`
   in the test suite holds that, so a five-column footer of dead links cannot be added
   later by accident.

   It is doing three jobs: second-chance navigation for someone who scrolled the whole
   page without clicking anything; surfacing two answers the landing page does NOT
   give (what it costs, and the FAQ) which were already written and previously
   unreachable from here; and carrying the trust line.

   ⏭ The company block (registered name, number, registered office) slots into
   .footer-bar beside the copyright when the company exists -- UK trading-disclosure
   rules require it on the website, so the space is deliberately left for it rather
   than the bar being sized to the copyright alone. */

.site-footer {
  border-top: 1px solid var(--border-secondary);
  background: var(--subtle-secondary);
  text-align: left;
  color: var(--text-secondary);
  padding: 0;
}
.footer-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: var(--space-14) var(--space-6) var(--space-10);
  display: grid;
  grid-template-columns: minmax(240px, 1.6fr) repeat(3, minmax(150px, 1fr));
  gap: var(--space-8);
}
@media (max-width: 860px) {
  .footer-inner { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .footer-brand { grid-column: 1 / -1; }
}

.footer-brand .logo { margin-bottom: var(--space-3); }
.footer-brand p { font-size: 14px; line-height: 1.7; max-width: 34ch; margin-bottom: var(--space-3); }
.footer-meta { color: var(--text-tertiary); font-size: 13px; }

.footer-nav h2 {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--space-4);
}
.footer-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.footer-nav a { font-size: 14px; color: var(--text-secondary); text-decoration: none; }
.footer-nav a:hover { color: var(--brand); text-decoration: underline; }

.footer-bar {
  border-top: 1px solid var(--border-secondary);
}
.footer-bar > * {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--space-6);
}
.footer-legal { padding-top: var(--space-6); font-size: 13px; color: var(--text-secondary); }
/* ⛔ Every clause here is checked, not assumed: `external refs in dist` returns
   nothing at all (the fonts are self-hosted precisely so no visitor IP reaches a
   third party), and the ONE thing stored is the theme key in localStorage. Worded as
   "remembered in your own browser" rather than "no cookies", because localStorage is
   storage even where it needs no consent, and a claim that is technically arguable is
   worth less than one that is plainly true. */
.footer-promise {
  padding-top: var(--space-2);
  padding-bottom: var(--space-8);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-tertiary);
  max-width: 62ch;
  text-wrap: pretty;
}
