/* ==========================================================================
   SitePaper
   Safety Documents. Made Simple.

   Contents
   01. Custom properties (brand tokens)
   02. Reset and base
   03. Layout helpers
   04. Typography
   05. Buttons
   06. Icons
   07. Header and navigation
   08. Hero
   09. How it works
   10. Document types
   11. Pricing
   12. FAQ accordion
   13. Closing CTA
   14. Footer
   15. Auth: session nav, forms, dashboard
   16. Document intake: request list, type picker, intake form
   17. Motion preferences
   18. Admin cockpit
   19. Legal page and acknowledgement
   20. Billing
   21. Subscription gate
   22. Conversion upgrade
   23. Utilities

   Mobile first. Every media query is min-width, so the base styles are
   the phone layout and breakpoints add complexity from there.

   Breakpoints used:
     560px  small phone to large phone
     760px  large phone to tablet
     900px  tablet to desktop nav (hamburger disappears here)
     1100px wide desktop
   ========================================================================== */


/* ==========================================================================
   01. Custom properties
   ========================================================================== */

:root {
  /* Brand colours */
  --colour-red:        #E01E2B;
  --colour-red-dark:   #B8151F;   /* hover / active state for red */
  --colour-red-tint:   #FDECED;   /* very light red for soft backgrounds */
  /* Brand red only reaches 3.95:1 on the near black. That clears the 3:1 bar
     for large text but not the 4.5:1 one for small text, so dark sections use
     this slightly lifted red for anything set small. 5.1:1 on #111111. */
  --colour-red-on-dark: #F4404D;
  --colour-ink:        #111111;
  --colour-white:      #FFFFFF;
  --colour-grey:       #F5F5F5;

  /* Derived neutrals, all sampled off the near black so greys stay warm-neutral */
  --colour-grey-200:   #E6E6E6;   /* borders */
  --colour-grey-400:   #B0B0B0;   /* muted text on dark */
  --colour-body:       #4A4A4A;   /* body copy, softer than pure ink */

  /* Status colours. Used by the risk chips in the hero mockup and by the
     request status badges on the dashboard, so they live in one place. */
  --colour-amber:      #E8A317;
  --colour-green:      #1F9D55;
  --colour-amber-tint: #FDF3E0;
  --colour-green-tint: #E8F6EE;
  --colour-amber-ink:  #7A5305;   /* amber text dark enough to read on tint */
  --colour-green-ink:  #14663A;

  /* Typography */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  /* Spacing scale */
  --space-xs:   0.5rem;
  --space-sm:   0.75rem;
  --space-md:   1.25rem;
  --space-lg:   2rem;
  --space-xl:   3rem;
  --space-2xl:  4.5rem;
  --space-3xl:  6rem;

  /* Radii */
  --radius-sm:  6px;
  --radius-md:  10px;
  --radius-lg:  16px;

  /* Shadows, kept subtle so cards read flat and modern */
  --shadow-sm:  0 1px 2px rgba(17, 17, 17, 0.05);
  --shadow-md:  0 4px 16px rgba(17, 17, 17, 0.07);
  --shadow-lg:  0 12px 32px rgba(17, 17, 17, 0.10);

  /* Layout */
  --container:        1180px;
  --container-narrow: 780px;
  --header-height:    68px;

  /* Motion */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}


/* ==========================================================================
   02. Reset and base
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  /* Anchor links land below the sticky header instead of underneath it. */
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-height) + 12px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--colour-body);
  background: var(--colour-white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
svg { display: block; max-width: 100%; }

ul, ol { margin: 0; padding: 0; list-style: none; }

p { margin: 0 0 var(--space-md); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--colour-red);
  text-decoration: none;
  transition: color 0.15s var(--ease);
}
a:hover { color: var(--colour-red-dark); }

button { font: inherit; color: inherit; }

/* Visible focus ring for keyboard users only, never on mouse clicks. */
:focus-visible {
  outline: 3px solid var(--colour-red);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--space-md);
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--colour-ink);
  color: var(--colour-white);
  font-weight: 600;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  transition: top 0.2s var(--ease);
}
.skip-link:focus {
  top: 0;
  color: var(--colour-white);
}


/* ==========================================================================
   03. Layout helpers
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-md);
}

.container--narrow { max-width: var(--container-narrow); }

@media (min-width: 760px) {
  .container { padding-inline: var(--space-lg); }
}

.section {
  padding-block: var(--space-2xl);
}

@media (min-width: 900px) {
  .section { padding-block: var(--space-3xl); }
}

.section--grey { background: var(--colour-grey); }

/* --- Dark section ----------------------------------------------------------
   Inverts a whole section onto the near black. Used on "How it works" to
   break up the white and grey run and anchor the top half of the page.

   Written as a modifier that recolours its own children rather than as
   one-off overrides, so any future section can go dark by adding the class.
   --------------------------------------------------------------------------- */

.section--dark {
  background: var(--colour-ink);
  color: var(--colour-grey-400);
}

.section--dark .section-title,
.section--dark .step__title {
  color: var(--colour-white);
}

.section--dark .section-lead,
.section--dark .step p {
  /* #B0B0B0 on #111111 is 8.7:1, comfortably past the 4.5:1 minimum. */
  color: var(--colour-grey-400);
}

/* Cards cannot use the white shell here, a white card on black is a glare
   box. Instead they lift off the background with a translucent white wash
   and a hairline border. Shadows do nothing on dark, so they are dropped. */
.section--dark .card {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.12);
  box-shadow: none;
}

/* Step numbers go red on dark. The light grey they use on white would be
   near invisible here, and red keeps them reading as an accent. At 28px and
   weight 800 they count as large text, so brand red's 3.95:1 is fine. */
.section--dark .step__number { color: var(--colour-red); }

/* The eyebrow is only 13px, so it needs the lifted red to stay legible. */
.section--dark .eyebrow { color: var(--colour-red-on-dark); }

/* Section headers are left aligned by default so they share the hero's left
   edge. Because .section-head is a direct child of .container, exactly like
   the grids underneath it, its text starts on the same line as the left edge
   of the first card. Nothing extra is needed to line them up.

   max-width keeps the intro paragraph to a readable measure without pulling
   the block off that left edge, since there is no auto margin. */
.section-head {
  max-width: 640px;
  margin-bottom: var(--space-xl);
}

@media (min-width: 900px) {
  .section-head { margin-bottom: var(--space-2xl); }
}

/* Opt-in centred variant, used by the dark "How it works" section where the
   centring is a deliberate contrast against the left aligned rest of the
   page. Stays left on mobile, same as everything else. */
@media (min-width: 900px) {
  .section-head--centred {
    margin-inline: auto;
    text-align: center;
  }
}

/* Shared card shell. Every card in the page builds off this. */
.card {
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}


/* ==========================================================================
   04. Typography
   ========================================================================== */

h1, h2, h3, h4 {
  margin: 0 0 var(--space-sm);
  color: var(--colour-ink);
  font-weight: 800;          /* headings sit heavier than body for that blocky SaaS look */
  line-height: 1.12;
  letter-spacing: -0.02em;
}

h3 { font-weight: 700; letter-spacing: -0.01em; line-height: 1.25; }

.eyebrow {
  margin: 0 0 var(--space-sm);
  color: var(--colour-red);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.section-title {
  font-size: clamp(1.75rem, 5.5vw, 2.75rem);
}

.section-lead {
  margin-top: var(--space-md);
  font-size: 1.0625rem;
  color: var(--colour-body);
}

@media (min-width: 760px) {
  .section-lead { font-size: 1.125rem; }
}


/* ==========================================================================
   05. Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: 0.75rem 1.5rem;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.15s var(--ease),
              border-color 0.15s var(--ease),
              color 0.15s var(--ease),
              transform 0.1s var(--ease);
}

.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--colour-red);
  border-color: var(--colour-red);
  color: var(--colour-white);
}
.btn--primary:hover {
  background: var(--colour-red-dark);
  border-color: var(--colour-red-dark);
  color: var(--colour-white);
}

.btn--outline {
  background: transparent;
  border-color: var(--colour-ink);
  color: var(--colour-ink);
}
.btn--outline:hover {
  background: var(--colour-ink);
  color: var(--colour-white);
}

.btn--sm { padding: 0.55rem 1.1rem; font-size: 0.875rem; }

.btn--lg {
  padding: 0.95rem 1.9rem;
  font-size: 1.0625rem;
}

.btn--block { display: flex; width: 100%; }


/* ==========================================================================
   06. Icons
   Every inline SVG is a 24x24 stroked icon inheriting currentColor.
   ========================================================================== */

.icon {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex-shrink: 0;
}

.icon--inline {
  width: 18px;
  height: 18px;
  display: inline-block;
  vertical-align: -0.2em;
}

.icon--check {
  width: 18px;
  height: 18px;
  stroke-width: 3;
  color: var(--colour-red);
}

/* Red square icon tile used by the step cards and doc cards. */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--colour-red);
  color: var(--colour-white);
}

.icon-badge--sm {
  width: 42px;
  height: 42px;
  margin-bottom: var(--space-sm);
  background: var(--colour-red-tint);
  color: var(--colour-red);
}


/* ==========================================================================
   07. Header and navigation
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--colour-grey-200);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-height: var(--header-height);
}

/* --- Wordmark ------------------------------------------------------------ */

/* The wordmark is now an <img> pointing at assets/logo.svg. The link is just
   a block wrapper, so it carries no type styling of its own. */
.wordmark {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;          /* stops the logo squashing next to the nav */
  line-height: 0;          /* kills the inline-image descender gap */
}

/* Logos are sized by height, with width:auto so the aspect ratio always comes
   from the file itself and can never be squashed. The nav and footer use two
   different files with different shapes, so they get their own heights.

   Both source files are far larger than their display size, so the browser is
   downscaling. That keeps them sharp on retina at the cost of bandwidth. See
   assets/README.md for the export sizes worth generating. */
.wordmark__img {
  width: auto;
}

/* --- Header logo: 2172x724, a 3:1 horizontal lockup -----------------------
   42px is the top of the 38 to 42 range because the artwork carries its own
   vertical padding. Only about 66% of the file's height is actual logo, so a
   42px box renders roughly 28px of visible mark. It reads as ~126px wide.
   42px inside the 68px header leaves 13px clear top and bottom. */
.site-header .wordmark__img { height: 42px; }

/* MOBILE WATCH: at 320px the container leaves 280px of usable width. The logo
   at 126px plus the 44px hamburger plus the 20px flex gap comes to 190px, so
   it already fits without shrinking. The step-down below is headroom, not a
   rescue: it keeps the gap generous on the narrowest phones rather than
   letting the two elements crowd each other.

   .wordmark carries flex-shrink:0, so the logo can never be squished by the
   flex row. It will always keep its true 3:1 proportions. */
@media (max-width: 420px) {
  .site-header .wordmark__img { height: 36px; }
}

/* --- Footer logo: 1536x1024, a 3:2 stacked lockup -------------------------
   Taller than the header logo because this version stacks the icon above the
   wordmark, so it needs the height to stay readable. 72px renders ~108px wide.
   Left at 72px on mobile too, since the footer is a single column there and
   has plenty of room. */
.wordmark--light .wordmark__img { height: 72px; }

/* --- Hamburger ----------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;               /* 44px keeps it a comfortable thumb target */
  height: 44px;
  padding: 0 10px;
  background: none;
  border: 0;
  cursor: pointer;
}

.nav-toggle__bar {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--colour-ink);
  border-radius: 2px;
  transition: transform 0.2s var(--ease), opacity 0.15s var(--ease);
}

/* Hamburger morphs into a cross while the panel is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* --- Mobile nav panel ----------------------------------------------------
   Below 900px the nav is a dropdown pinned under the header. It is hidden
   with display:none via the [hidden] attribute that main.js manages, so
   links are not reachable by keyboard while closed.
   ------------------------------------------------------------------------- */

.primary-nav {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: var(--space-md) var(--space-md) var(--space-lg);
  background: var(--colour-white);
  border-bottom: 1px solid var(--colour-grey-200);
  box-shadow: var(--shadow-md);
  /* MOBILE WATCH: on very short landscape phones a long menu could overflow,
     so the panel scrolls rather than pushing content off screen. */
  max-height: calc(100vh - var(--header-height));
  overflow-y: auto;
}

.primary-nav__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: var(--space-md);
}

.primary-nav__list a {
  display: block;
  padding: 0.7rem 0;
  color: var(--colour-ink);
  font-weight: 600;
  border-bottom: 1px solid var(--colour-grey-200);
}
.primary-nav__list a:hover { color: var(--colour-red); }

/* --- Desktop nav --------------------------------------------------------- */

@media (min-width: 900px) {
  .nav-toggle { display: none; }

  /* Reset the panel back to an inline row. The [hidden] attribute is stripped
     by main.js at this width, but the display rule here is a safety net. */
  .primary-nav,
  .primary-nav[hidden] {
    display: flex;
    position: static;
    align-items: center;
    gap: var(--space-lg);
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    max-height: none;
    overflow: visible;
  }

  .primary-nav__list {
    flex-direction: row;
    align-items: center;
    gap: var(--space-lg);
    margin-bottom: 0;
  }

  .primary-nav__list a {
    padding: 0;
    border: 0;
    font-size: 0.9375rem;
  }

}


/* ==========================================================================
   08. Hero
   ========================================================================== */

.hero {
  position: relative;
  padding-block: var(--space-2xl) var(--space-2xl);
  background:
    radial-gradient(70rem 30rem at 50% -18rem, rgba(224, 30, 43, 0.10), transparent 70%),
    var(--colour-white);
  border-bottom: 1px solid var(--colour-grey-200);
  overflow: hidden;
}

@media (min-width: 900px) {
  .hero { padding-block: var(--space-3xl) var(--space-3xl); }
}

/* --- Hero layout ----------------------------------------------------------
   Mobile first: one column, copy first, visual stacked underneath. At 1000px
   it splits into two equal halves with the copy left aligned.

   1000px rather than the 900px nav breakpoint because the document mockup
   needs roughly 380px of column to stay legible. Between 900 and 1000 the
   nav is already inline while the hero is still stacked, which reads fine.
   ------------------------------------------------------------------------- */

.hero__grid {
  display: grid;
  gap: var(--space-xl);
}

@media (min-width: 1000px) {
  .hero__grid {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--space-2xl);
  }
}

.hero__content { max-width: 820px; }

.hero__title {
  /* clamp keeps the headline from swallowing a 320px screen while still
     going properly big on desktop. */
  font-size: clamp(2.125rem, 8vw, 4rem);
  margin-bottom: var(--space-md);
}

/* Once the hero splits in two the headline only has half the width to play
   with, so the ceiling comes down. The hard <br> is dropped here too: at this
   width it forced "starts." onto a line of its own. text-wrap:balance lets the
   browser even out the line lengths instead. Browsers without it just wrap
   normally, which is the same result minus the tidy ragging. */
@media (min-width: 1000px) {
  .hero__title {
    font-size: clamp(2.5rem, 3.6vw, 3.25rem);
    text-wrap: balance;
  }
  .hero__title br { display: none; }
}

/* MOBILE WATCH: the <br> in the headline is a desktop nicety. Below 760px we
   let the browser wrap naturally so the line break does not land awkwardly. */
@media (max-width: 759px) {
  .hero__title br { display: none; }
}

.hero__sub {
  max-width: 620px;
  font-size: 1.0625rem;
  color: var(--colour-body);
}

@media (min-width: 760px) {
  .hero__sub { font-size: 1.1875rem; }
}

.hero__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
}

@media (min-width: 560px) {
  /* Side by side once there is room for two full width buttons. */
  .hero__actions { flex-direction: row; flex-wrap: wrap; }
}

.hero__trust {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  margin-top: var(--space-lg);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--colour-body);
}


/* --- Hero visual: CSS-only SWMS preview ------------------------------------
   No image file. The whole document is built from divs so it stays sharp at
   any size and costs nothing to load.

   Everything inside sizes in em, so .doc-mock's font-size is the single dial
   that scales the entire document. Change that one value and the header, the
   bars, the chips and the stamp all resize together in proportion.
   --------------------------------------------------------------------------- */

.hero__visual {
  display: flex;
  justify-content: center;
  /* Slack so the rotation and the soft shadow are never clipped by the
     hero's overflow:hidden. */
  padding-inline: 0.75rem;
}

.doc-mock {
  position: relative;
  width: 100%;
  max-width: 30em;
  font-size: 10.5px;   /* the master scale dial */
}

@media (min-width: 480px) { .doc-mock { font-size: 12px; } }
@media (min-width: 1180px) { .doc-mock { font-size: 13.5px; } }

/* Warm glow pooled behind the sheet. Sits inside .doc-mock's own stacking
   context (created by the transform below) so z-index:-1 cannot escape
   behind the hero background. */
.doc-mock::before {
  content: '';
  position: absolute;
  inset: -10%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(224, 30, 43, 0.14), transparent 72%);
}

/* MOBILE WATCH: the card is flat below 480px on purpose. At 320px the sheet
   fills nearly the whole container, and rotating it would push the corners
   into the hero's overflow:hidden and shave them off. It keeps the floating
   shadow, just without the tilt. */
@media (min-width: 480px) {
  .doc-mock {
    transform: rotate(-2.5deg);
    animation: doc-float 7s var(--ease) infinite;
  }
}

@keyframes doc-float {
  0%, 100% { transform: rotate(-2.5deg) translateY(0); }
  50%      { transform: rotate(-2.5deg) translateY(-0.85em); }
}

/* Ghost sheets peeking out behind, so it reads as a stack of documents
   rather than a single floating rectangle. */
.doc-mock__stack {
  position: absolute;
  inset: 0;
  border-radius: 1em;
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
}

.doc-mock__stack--1 { transform: translate(0.85em, -0.85em) rotate(2deg); }
.doc-mock__stack--2 { transform: translate(1.7em, -1.7em) rotate(4deg); opacity: 0.55; }

.doc-mock__sheet {
  position: relative;
  border-radius: 1em;
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  overflow: hidden;    /* keeps the red header inside the rounded corners */
  /* Three stacked shadows: a tight contact shadow, a mid lift and a wide
     ambient pool. Reads far softer than one big blur. */
  box-shadow:
    0 0.15em 0.3em rgba(17, 17, 17, 0.04),
    0 0.9em 1.8em rgba(17, 17, 17, 0.08),
    0 2.4em 4.8em rgba(17, 17, 17, 0.13);
}

/* Red header bar */
.doc-mock__header {
  padding: 1.15em 1.35em 1.25em;
  background: var(--colour-red);
  color: var(--colour-white);
}

.doc-mock__kicker {
  margin: 0 0 0.5em;
  font-size: 0.72em;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
}

.doc-mock__title {
  margin: 0 0 0.45em;
  color: var(--colour-white);
  font-size: 1.35em;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.doc-mock__ref {
  margin: 0;
  font-size: 0.78em;
  font-weight: 500;
  opacity: 0.8;
}

/* Document body */
.doc-mock__body {
  display: grid;
  gap: 1.15em;
  padding: 1.35em;
}

.doc-mock__meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9em;
}

.doc-mock__meta-item { display: grid; gap: 0.45em; }

.doc-mock__label {
  font-size: 0.7em;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--colour-red);
}

/* Grey bars standing in for lines of text */
.doc-mock__bar {
  display: block;
  height: 0.62em;
  border-radius: 0.31em;
  background: var(--colour-grey-200);
}

.doc-mock__section {
  margin: 0;
  color: var(--colour-ink);
  font-size: 0.82em;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* Risk rows: a severity chip beside each control line */
.doc-mock__rows { display: grid; gap: 0.6em; }

.doc-mock__row {
  display: flex;
  align-items: center;
  gap: 0.7em;
}

.doc-mock__chip {
  flex: none;
  display: grid;
  place-items: center;
  width: 2em;
  height: 2em;
  border-radius: 0.4em;
  font-size: 0.7em;
  font-weight: 800;
  color: var(--colour-white);
}

.doc-mock__chip--high { background: var(--colour-red); }
.doc-mock__chip--med  { background: var(--colour-amber); }
.doc-mock__chip--low  { background: var(--colour-green); }

/* Signature block */
.doc-mock__sign {
  display: grid;
  gap: 0.55em;
  padding-top: 0.95em;
  border-top: 1px dashed var(--colour-grey-200);
}

.doc-mock__rule {
  display: block;
  height: 0.62em;
  border-radius: 0.31em;
  background: var(--colour-grey-200);
}

.doc-mock__rule--short { width: 45%; }

/* Compliance stamp. Sibling of the sheet, not a child, so the sheet's
   overflow:hidden cannot clip it where it hangs off the corner. */
.doc-mock__stamp {
  position: absolute;
  right: -0.5em;
  bottom: 1.8em;
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.62em 0.95em;
  border-radius: 0.6em;
  background: #1F9D55;
  color: var(--colour-white);
  font-weight: 800;
  letter-spacing: -0.01em;
  box-shadow: 0 0.5em 1.2em rgba(31, 157, 85, 0.35);
  transform: rotate(4deg);
}

.doc-mock__stamp-icon {
  width: 1.15em;
  height: 1.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 3.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.doc-mock__stamp-text { font-size: 0.85em; }


/* ==========================================================================
   09. How it works
   ========================================================================== */

.steps {
  display: grid;
  gap: var(--space-md);
}

@media (min-width: 760px) {
  .steps { grid-template-columns: repeat(3, 1fr); gap: var(--space-lg); }
}

.step {
  position: relative;
  padding: var(--space-lg);
}

.step__number {
  position: absolute;
  top: var(--space-lg);
  right: var(--space-lg);
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--colour-grey-200);
  line-height: 1;
}

.step__title { font-size: 1.1875rem; }

.step p { font-size: 0.9375rem; }


/* ==========================================================================
   10. Document types
   ========================================================================== */

.doc-grid {
  display: grid;
  gap: var(--space-sm);
  /* auto-fit means the grid decides its own column count. 150px keeps two
     cards side by side on a 375px phone so ten of them do not turn into an
     endless scroll. It then steps up to 3, 4 and 5 across on wider screens.

     MOBILE WATCH: below about 340px the two column layout gets cramped and
     longer titles like "Plant & Equipment Checklists" wrap to three lines.
     Drop this to 200px if you would rather force a single column there. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

@media (min-width: 760px) {
  .doc-grid {
    gap: var(--space-md);
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  }
}

.doc-card { padding: var(--space-md); }

.doc-card__title {
  font-size: 1rem;
  margin-bottom: 0.25rem;
}

.doc-card__desc {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--colour-body);
}

.doc-grid__note {
  margin-top: var(--space-lg);
  font-size: 0.9375rem;
  color: var(--colour-body);
}

@media (min-width: 900px) {
  .doc-grid__note { text-align: center; }
}


/* ==========================================================================
   11. Pricing
   ========================================================================== */

.pricing {
  display: grid;
  gap: var(--space-lg);
  align-items: start;
}

@media (min-width: 900px) {
  .pricing { grid-template-columns: repeat(3, 1fr); gap: var(--space-md); }
}

@media (min-width: 1100px) {
  .pricing { gap: var(--space-lg); }
}

.plan {
  display: flex;
  flex-direction: column;
  padding: var(--space-lg);
}

.plan--featured {
  border: 2px solid var(--colour-red);
  box-shadow: var(--shadow-lg);
}

/* Lift the popular card only once the cards sit in a row. On mobile a lifted
   card just leaves an odd gap and pushes the badge into the card above it. */
@media (min-width: 900px) {
  .plan--featured { transform: translateY(-12px); }
}

.plan__badge {
  align-self: flex-start;
  margin-bottom: var(--space-sm);
  padding: 0.3rem 0.75rem;
  background: var(--colour-red);
  color: var(--colour-white);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.plan__name {
  font-size: 1.375rem;
  margin-bottom: 0.25rem;
}

.plan__descriptor {
  margin-bottom: var(--space-md);
  font-size: 0.9375rem;
  color: var(--colour-body);
}

.plan__price {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  margin-bottom: var(--space-md);
}

.plan__amount {
  font-size: 3rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--colour-ink);
}

.plan__period {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--colour-body);
}

/* Turnaround is the differentiator, so it gets its own tinted strip rather
   than sitting in the feature list. */
.plan__turnaround {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 0.7rem 0.9rem;
  margin-bottom: var(--space-sm);
  background: var(--colour-grey);
  border-radius: var(--radius-sm);
  color: var(--colour-ink);
  font-size: 1rem;
}

.plan__turnaround strong {
  font-weight: 800;
  letter-spacing: -0.01em;
}

.plan__turnaround .icon { width: 20px; height: 20px; color: var(--colour-red); }

.plan__turnaround--featured {
  background: var(--colour-red);
  color: var(--colour-white);
}
.plan__turnaround--featured .icon { color: var(--colour-white); }

.plan__docs {
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--colour-grey-200);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--colour-ink);
}

.plan__features {
  display: grid;
  gap: var(--space-sm);
  margin-bottom: var(--space-lg);
  /* Pushes the button to the bottom so all three cards line up. */
  flex-grow: 1;
  align-content: start;
}

.plan__features li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.plan__features .icon--check { margin-top: 2px; }

.pricing__note {
  margin-top: var(--space-lg);
  font-size: 0.875rem;
  color: var(--colour-body);
}

@media (min-width: 900px) {
  .pricing__note { text-align: center; }
}


/* ==========================================================================
   12. FAQ accordion
   Panels are toggled by main.js. It sets [hidden] for accessibility and
   animates max-height for the open/close motion.
   ========================================================================== */

.faq {
  display: grid;
  gap: var(--space-sm);
}

.faq__item {
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.faq h3 { margin: 0; }

.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  width: 100%;
  padding: var(--space-md);
  background: none;
  border: 0;
  text-align: left;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
  cursor: pointer;
  transition: color 0.15s var(--ease);
}

.faq__question:hover { color: var(--colour-red); }

.faq__question[aria-expanded="true"] { color: var(--colour-red); }

.faq__chevron {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.2s var(--ease);
}

.faq__question[aria-expanded="true"] .faq__chevron { transform: rotate(180deg); }

.faq__panel {
  overflow: hidden;
  transition: max-height 0.25s var(--ease);
}

.faq__panel-inner {
  padding: 0 var(--space-md) var(--space-md);
  font-size: 0.9375rem;
  color: var(--colour-body);
}

@media (min-width: 760px) {
  .faq__question { font-size: 1.0625rem; padding: var(--space-md) var(--space-lg); }
  .faq__panel-inner { padding: 0 var(--space-lg) var(--space-lg); font-size: 1rem; }
}


/* ==========================================================================
   13. Closing CTA
   ========================================================================== */

.cta {
  padding-block: var(--space-2xl);
  background: var(--colour-ink);
  color: var(--colour-white);
}

.cta__inner { text-align: center; }

.cta__title {
  color: var(--colour-white);
  font-size: clamp(1.625rem, 5vw, 2.5rem);
}

.cta__sub {
  max-width: 520px;
  margin: 0 auto var(--space-lg);
  color: var(--colour-grey-400);
  font-size: 1.0625rem;
}


/* ==========================================================================
   14. Footer
   ========================================================================== */

.site-footer {
  padding-block: var(--space-xl) var(--space-lg);
  background: var(--colour-ink);
  color: var(--colour-grey-400);
  font-size: 0.9375rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.footer__top {
  display: grid;
  gap: var(--space-xl);
  padding-bottom: var(--space-xl);
}

@media (min-width: 760px) {
  /* Brand column takes the slack, the two link columns stay compact. */
  .footer__top {
    grid-template-columns: 2fr 1fr 1fr;
    gap: var(--space-lg);
  }
}

.footer__tagline {
  margin: var(--space-sm) 0 var(--space-xs);
  color: var(--colour-white);
  font-weight: 600;
}

.footer__location { margin: 0; }

.footer__heading {
  margin-bottom: var(--space-sm);
  color: var(--colour-white);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.footer__nav ul { display: grid; gap: 0.6rem; }

.footer__nav a { color: var(--colour-grey-400); }
.footer__nav a:hover { color: var(--colour-white); }

.footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-top: var(--space-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  font-size: 0.875rem;
}

@media (min-width: 760px) {
  .footer__bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.footer__bottom p { margin: 0; }

.footer__credit a {
  color: var(--colour-white);
  font-weight: 600;
  border-bottom: 1px solid var(--colour-red);
  padding-bottom: 1px;
}
.footer__credit a:hover { color: var(--colour-red); }


/* ==========================================================================
   15. Auth: session nav, forms, dashboard
   ========================================================================== */

/* --- Session aware nav -----------------------------------------------------
   The container ships as data-auth-state="unknown" and js/auth.js flips it to
   "in" or "out" once the session is known. "unknown" deliberately renders the
   logged out controls, so the nav looks right before any JS runs and for
   anyone without JS at all.
   --------------------------------------------------------------------------- */

/* Mobile first: inside the dropdown panel the controls stack full width,
   the same way the single CTA used to. They become an inline row at 900px. */
.nav-auth {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-sm);
  width: 100%;
}

.nav-auth .btn { width: 100%; }

/* Logged out view is the default, so hide the logged in controls until we
   positively know there is a session. */
.nav-auth[data-auth-state="unknown"] .nav-auth__in,
.nav-auth[data-auth-state="out"] .nav-auth__in { display: none; }

.nav-auth[data-auth-state="in"] .nav-auth__out { display: none; }

.nav-auth__link {
  color: var(--colour-ink);
  font-weight: 600;
  font-size: 0.9375rem;
  white-space: nowrap;
}
.nav-auth__link:hover { color: var(--colour-red); }

/* In the stacked panel the Dashboard link matches the other nav links, with
   a divider rule under it. Inline on desktop, so the rule comes off. */
.nav-auth__link {
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--colour-grey-200);
}

@media (min-width: 900px) {
  .nav-auth { flex-direction: row; align-items: center; width: auto; }
  .nav-auth .btn { width: auto; }
  .nav-auth__link { padding: 0; border: 0; }
}


/* --- Page shell for the short auth pages -----------------------------------
   Signup and login are much shorter than the home page, so without this the
   footer floats up the screen. Pins it to the bottom on tall viewports while
   still scrolling normally when the content is taller.
   --------------------------------------------------------------------------- */

.layout-fill {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.layout-fill main { flex: 1 0 auto; }


/* --- Centred auth card ----------------------------------------------------- */

.auth {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: var(--space-2xl);
  /* Same warm wash as the hero, so the auth pages feel like the same site. */
  background:
    radial-gradient(60rem 26rem at 50% -14rem, rgba(224, 30, 43, 0.10), transparent 70%),
    var(--colour-grey);
}

@media (min-width: 760px) {
  .auth { padding-block: var(--space-3xl); }
}

.auth__inner {
  width: 100%;
  max-width: 27rem;   /* comfortable single column form width */
}

.auth-card {
  padding: var(--space-lg);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

@media (min-width: 560px) {
  .auth-card { padding: var(--space-xl); }
}

.auth-card__head { margin-bottom: var(--space-lg); }

.auth-card__title {
  margin-bottom: var(--space-xs);
  font-size: 1.75rem;
}

.auth-card__sub {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--colour-body);
}

.auth-card__foot {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--colour-grey-200);
  font-size: 0.9375rem;
  text-align: center;
  color: var(--colour-body);
}

.auth-card__foot a { font-weight: 600; }


/* --- Form fields ----------------------------------------------------------- */

.form { display: grid; gap: var(--space-md); }

.field { display: grid; gap: 0.4rem; }

.field__label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--colour-ink);
}

.field__input {
  width: 100%;
  padding: 0.8rem 0.9rem;
  font-family: inherit;
  /* 16px minimum. Anything smaller makes iOS Safari zoom the page in when the
     field is focused, which throws the layout around. */
  font-size: 1rem;
  color: var(--colour-ink);
  background: var(--colour-white);
  border: 1.5px solid var(--colour-grey-200);
  border-radius: var(--radius-sm);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.field__input::placeholder { color: #9A9A9A; }

.field__input:hover { border-color: #CFCFCF; }

.field__input:focus {
  outline: none;   /* replaced by the ring below, not removed outright */
  border-color: var(--colour-red);
  box-shadow: 0 0 0 3px rgba(224, 30, 43, 0.16);
}

.field__hint {
  font-size: 0.8125rem;
  color: var(--colour-body);
}

/* Error state: red border plus a message line. Colour is never the only
   signal, the text below carries the actual reason. */
.field--error .field__input {
  border-color: var(--colour-red);
  background: var(--colour-red-tint);
}

.field--error .field__input:focus {
  box-shadow: 0 0 0 3px rgba(224, 30, 43, 0.22);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: 0.3rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--colour-red-dark);
}


/* --- Form level banner ------------------------------------------------------
   One box above the fields for anything that is not tied to a single input:
   API failures, and the signup success message.
   --------------------------------------------------------------------------- */

.form-alert {
  padding: 0.8rem 0.95rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: 0.9375rem;
  font-weight: 500;
}

.form-alert--error {
  background: var(--colour-red-tint);
  border-color: rgba(224, 30, 43, 0.35);
  color: #8E1019;   /* darkened for contrast on the pink wash */
}

.form-alert--success {
  background: #E8F6EE;
  border-color: rgba(31, 157, 85, 0.35);
  color: #14663A;
}

.btn:disabled {
  opacity: 0.65;
  cursor: not-allowed;
}


/* --- Dashboard -------------------------------------------------------------- */

/* Shown while the session check runs, so the protected shell is never
   painted before we know the visitor is allowed to see it. */
.dash-checking {
  padding-block: var(--space-3xl);
  text-align: center;
  color: var(--colour-body);
}

.dash__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding-bottom: var(--space-lg);
  border-bottom: 1px solid var(--colour-grey-200);
}

@media (min-width: 640px) {
  .dash__head {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
  }
}

.dash__title {
  margin-bottom: 0.35rem;
  font-size: clamp(1.75rem, 5vw, 2.5rem);
}

.dash__email {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--colour-red);
  /* Long addresses should wrap rather than push the log out button off. */
  overflow-wrap: anywhere;
}

/* Empty state standing in for the portal we build next. */
.dash__placeholder {
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-xl);
  padding: var(--space-2xl) var(--space-md);
  text-align: center;
  background: var(--colour-grey);
  border: 2px dashed var(--colour-grey-200);
  border-radius: var(--radius-lg);
}

.dash__placeholder .icon {
  width: 40px;
  height: 40px;
  color: var(--colour-red);
}

.dash__placeholder p {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--colour-ink);
}

.dash__placeholder span {
  font-size: 0.9375rem;
  color: var(--colour-body);
}


/* ==========================================================================
   16. Document intake: request list, type picker, intake form
   ========================================================================== */

/* --- Dashboard: action bar and request list -------------------------------- */

.dash__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-xl);
}

@media (min-width: 560px) {
  .dash__actions { flex-direction: row; align-items: center; }
}

.dash__section-title {
  margin: var(--space-xl) 0 var(--space-md);
  font-size: 1.125rem;
}

/* Textarea shares the input styling, so .field--error and :focus rules in
   section 15 apply to both without duplication. */
textarea.field__input {
  min-height: 7rem;
  line-height: 1.6;
  resize: vertical;
}

textarea.field__input--tall { min-height: 10rem; }

.request-list { display: grid; gap: var(--space-sm); }

.request-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

@media (min-width: 640px) {
  .request-item {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
  }
}

.request-item__main { min-width: 0; }   /* lets long names truncate not overflow */

.request-item__type {
  margin: 0 0 0.15rem;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
}

.request-item__site {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--colour-body);
  overflow-wrap: anywhere;
}

.request-item__date {
  margin: 0.2rem 0 0;
  font-size: 0.8125rem;
  color: var(--colour-body);
}

/* --- Status badge -----------------------------------------------------------
   Colour is a reinforcement, never the only signal. The status word itself is
   always in the badge, so it still reads correctly in greyscale.
   --------------------------------------------------------------------------- */

.status-badge {
  flex: none;
  align-self: flex-start;
  padding: 0.3rem 0.7rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.status-badge--submitted {
  background: var(--colour-grey);
  border-color: var(--colour-grey-200);
  color: var(--colour-body);
}

.status-badge--progress {
  background: var(--colour-amber-tint);
  border-color: rgba(232, 163, 23, 0.45);
  color: var(--colour-amber-ink);
}

.status-badge--delivered {
  background: var(--colour-green-tint);
  border-color: rgba(31, 157, 85, 0.4);
  color: var(--colour-green-ink);
}

/* --- Empty and loading states ----------------------------------------------- */

.state-note {
  padding: var(--space-md);
  font-size: 0.9375rem;
  color: var(--colour-body);
  text-align: center;
}


/* --- Step 1: document type picker -------------------------------------------
   Real <button>s, not divs, so keyboard and screen reader users get them for
   free. One column on phones, filling out to four across on desktop.
   --------------------------------------------------------------------------- */

.typepick {
  display: grid;
  gap: var(--space-sm);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

@media (min-width: 760px) {
  .typepick { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}

.typepick__btn {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  text-align: left;
  background: var(--colour-white);
  border: 1.5px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color 0.15s var(--ease),
              box-shadow 0.15s var(--ease),
              transform 0.1s var(--ease);
}

.typepick__btn:hover {
  border-color: var(--colour-red);
  box-shadow: var(--shadow-md);
}

.typepick__btn:active { transform: translateY(1px); }

.typepick__btn .icon {
  width: 20px;
  height: 20px;
  color: var(--colour-red);
}

.typepick__label {
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
  line-height: 1.3;
}


/* --- Wizard shell -----------------------------------------------------------
   Named .wizard rather than .step, because .step is already the how it works
   card on the home page.
   --------------------------------------------------------------------------- */

.wizard__count {
  margin: 0 0 var(--space-xs);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--colour-red);
}

.wizard__title {
  margin-bottom: var(--space-xs);
  font-size: clamp(1.5rem, 4.5vw, 2.125rem);
}

.wizard__lead {
  max-width: 46rem;
  margin-bottom: var(--space-lg);
  color: var(--colour-body);
}

/* The chosen type, carried across to step 2 with a way back to change it. */
.chosen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-lg);
  background: var(--colour-grey);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
}

.chosen__label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--colour-body);
}

.chosen__value {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
}

/* Text button, sits at the end of the chosen bar. */
.chosen__change {
  margin-left: auto;
  padding: 0;
  background: none;
  border: 0;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--colour-red);
  text-decoration: underline;
  cursor: pointer;
}
.chosen__change:hover { color: var(--colour-red-dark); }


/* --- Intake form ------------------------------------------------------------- */

.intake {
  max-width: 46rem;
  padding: var(--space-lg);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

@media (min-width: 560px) {
  .intake { padding: var(--space-xl); }
}

/* Label row, so the "Important" pill can sit beside the label text. */
.field__label-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
}

/* Marks the two fields that actually drive document quality. */
.pill-important {
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.3);
  color: var(--colour-red-dark);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.intake__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--colour-grey-200);
}

@media (min-width: 560px) {
  .intake__actions { flex-direction: row-reverse; justify-content: flex-end; }
}


/* --- Step 3: success ---------------------------------------------------------- */

.result {
  max-width: 34rem;
  /* Centred in the container with even margins either side. Below 34rem the
     card just fills the width, so this is a no-op on phones and the padding
     on .container keeps it off the screen edges. */
  margin-inline: auto;
  padding: var(--space-xl) var(--space-lg);
  text-align: center;
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.result__tick {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin: 0 auto var(--space-md);
  border-radius: 50%;
  background: var(--colour-green-tint);
  color: var(--colour-green);
}

.result__tick .icon { width: 32px; height: 32px; stroke-width: 3; }

.result__title { font-size: 1.5rem; margin-bottom: var(--space-xs); }

.result__sub { color: var(--colour-body); }

.result__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
}

@media (min-width: 480px) {
  .result__actions { flex-direction: row; justify-content: center; }
}

/* Shown only when the row saved but the notification email did not go out.
   Deliberately low key: the submission itself is safe, so this must not read
   like a failure to the person who just filled the form in. */
.result__warning {
  margin-top: var(--space-md);
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  background: var(--colour-amber-tint);
  border: 1px solid rgba(232, 163, 23, 0.45);
  color: var(--colour-amber-ink);
  font-size: 0.875rem;
  text-align: left;
}


/* ==========================================================================
   17. Motion preferences
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ==========================================================================
   18. Admin cockpit
   ========================================================================== */

/* Badge and download button stack on phones, sit side by side from 640px. */
.request-item__side {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

@media (min-width: 640px) {
  .request-item__side { flex: none; justify-content: flex-end; }
}

.admin__meta {
  margin: 0.35rem 0 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--colour-red);
}

/* --- Workload counters ------------------------------------------------------ */

.admin-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-sm);
  margin-top: var(--space-lg);
}

.admin-stat {
  padding: var(--space-md);
  text-align: center;
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
}

.admin-stat--done { background: var(--colour-green-tint); border-color: rgba(31,157,85,0.3); }

.admin-stat__num {
  display: block;
  font-size: 1.75rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--colour-ink);
}

.admin-stat__label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--colour-body);
}

/* --- Request cards ----------------------------------------------------------
   The open vs delivered distinction is carried by a thick left border, which
   reads instantly down a long list. Colour is backed up by the status badge
   text, so it still works in greyscale.
   --------------------------------------------------------------------------- */

.admin-list {
  display: grid;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.admin-card {
  padding: var(--space-md);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-left: 5px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

@media (min-width: 760px) {
  .admin-card { padding: var(--space-lg); }
}

/* Still to action: red edge, full white card. */
.admin-card--open { border-left-color: var(--colour-red); }

/* Done: green edge, and the whole card recedes so the open ones dominate. */
.admin-card--delivered {
  border-left-color: var(--colour-green);
  background: #FBFDFC;
}

.admin-card__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--colour-grey-200);
}

@media (min-width: 640px) {
  .admin-card__head {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
  }
}

.admin-card__heading { min-width: 0; }

.admin-card__type {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
}

.admin-card__site {
  margin: 0.1rem 0 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--colour-body);
  overflow-wrap: anywhere;
}

.admin-card__client {
  margin: 0.3rem 0 0;
  font-size: 0.8125rem;
  color: var(--colour-body);
  overflow-wrap: anywhere;
}

/* --- Submission detail ------------------------------------------------------ */

.admin-details {
  display: grid;
  gap: var(--space-md);
  padding: var(--space-md) 0;
}

@media (min-width: 760px) {
  .admin-details { grid-template-columns: 1fr 1fr; }
}

/* Free text fields get the full row, since they are the long ones. */
.admin-detail--wide { grid-column: 1 / -1; }

.admin-detail__label {
  display: block;
  margin-bottom: 0.2rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--colour-red);
}

.admin-detail__value {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--colour-ink);
  /* Preserve the line breaks the client typed into the textareas. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.admin-detail__value--empty {
  color: var(--colour-grey-400);
  font-style: italic;
}

/* --- Actions ----------------------------------------------------------------- */

.admin-actions {
  display: grid;
  gap: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px solid var(--colour-grey-200);
}

@media (min-width: 640px) {
  .admin-actions { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); align-items: end; }
}

.admin-action { display: grid; gap: 0.35rem; }

.admin-action__label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--colour-body);
}

.admin-select { cursor: pointer; }

/* File input: the native control, tidied rather than replaced, so it keeps
   its keyboard behaviour and its "no file chosen" state. */
.admin-file {
  width: 100%;
  padding: 0.55rem 0.7rem;
  font-family: inherit;
  font-size: 0.875rem;
  color: var(--colour-ink);
  background: var(--colour-white);
  border: 1.5px dashed var(--colour-grey-200);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.admin-file:hover { border-color: var(--colour-red); }

.admin-file::file-selector-button {
  margin-right: 0.7rem;
  padding: 0.4rem 0.8rem;
  font: inherit;
  font-weight: 700;
  font-size: 0.8125rem;
  color: var(--colour-white);
  background: var(--colour-ink);
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.admin-file::file-selector-button:hover { background: var(--colour-red); }

.admin-file:disabled { opacity: 0.6; cursor: wait; }

.admin-current {
  margin: var(--space-sm) 0 0;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--colour-green-ink);
  overflow-wrap: anywhere;
}

/* Per card feedback after an upload or status change. */
.admin-note {
  margin: var(--space-sm) 0 0;
  padding: 0.55rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  font-weight: 500;
}

.admin-note--info  { background: var(--colour-grey);       color: var(--colour-body); }
.admin-note--ok    { background: var(--colour-green-tint); color: var(--colour-green-ink); }
.admin-note--error { background: var(--colour-red-tint);   color: #8E1019; }


/* ==========================================================================
   19. Legal page and acknowledgement
   ========================================================================== */

/* --- disclaimer.html --------------------------------------------------------
   Long-form legal prose. Measure is capped by .container--narrow, and the
   type is set slightly larger with generous leading, because this is text
   people have to actually read rather than skim.
   --------------------------------------------------------------------------- */

.legal {
  max-width: 42rem;
  padding: var(--space-lg);
  background: var(--colour-white);
  border: 1px solid var(--colour-grey-200);
  border-left: 5px solid var(--colour-red);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

@media (min-width: 560px) {
  .legal { padding: var(--space-xl); }
}

.legal p {
  margin: 0 0 var(--space-md);
  font-size: 1rem;
  line-height: 1.75;
  color: var(--colour-ink);
}

@media (min-width: 760px) {
  .legal p { font-size: 1.0625rem; }
}

.legal p:last-child { margin-bottom: 0; }


/* --- Intake acknowledgement --------------------------------------------------
   Sits directly above the submit button, which is disabled until this is
   ticked. Given a tinted panel so it reads as a gate rather than an optional
   extra field.
   --------------------------------------------------------------------------- */

.ack {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
  padding: var(--space-md);
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.3);
  border-radius: var(--radius-md);
}

/* 20px box with a matching top nudge so it aligns to the first line of text
   rather than floating above it. Kept as a real checkbox so it keeps native
   keyboard and screen reader behaviour. */
.ack__box {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0.2rem 0 0;
  accent-color: var(--colour-red);
  cursor: pointer;
}

.ack__label {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--colour-ink);
  cursor: pointer;
}

/* Shown when someone submits without ticking, via Enter in a text field. */
.ack__error { margin-top: var(--space-xs); }


/* ==========================================================================
   20. Billing
   ========================================================================== */

.billing {
  display: grid;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
  padding: var(--space-md);
  background: var(--colour-grey);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
}

@media (min-width: 560px) {
  .billing { padding: var(--space-lg); }
}

/* Both states share this row: details left, action right. */
.billing__active,
.billing__none {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

@media (min-width: 640px) {
  .billing__active,
  .billing__none {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.billing__info { min-width: 0; }

.billing__label {
  margin: 0 0 0.2rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--colour-body);
}

.billing__plan {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin: 0;
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--colour-ink);
}

.billing__noplan {
  color: var(--colour-body);
  font-weight: 700;
}

.billing__renews,
.billing__prompt {
  margin: 0.35rem 0 0;
  font-size: 0.875rem;
  color: var(--colour-body);
}

.billing .btn { flex: none; }


/* Inline failure under a pricing card, so a dead click is never silent. */
.plan__error {
  margin: var(--space-sm) 0 0;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.35);
  color: #8E1019;
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: left;
}

/* Checkout buttons while the session is being created. */
.btn.is-busy { opacity: 0.7; pointer-events: none; }


/* ==========================================================================
   21. Subscription gate
   ========================================================================== */

/* Shown in place of the "Start a new document" button, and in place of the
   whole intake wizard, when the user has no active plan. */
.gate {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-lg);
  padding: var(--space-md);
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.3);
  border-radius: var(--radius-md);
}

@media (min-width: 760px) {
  .gate {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-lg);
  }
}

/* Standalone version on new-request.html, where it is the whole page. */
.gate--page {
  max-width: 46rem;
  margin-top: 0;
}

.gate__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  min-width: 0;
}

.gate__icon {
  flex: none;
  width: 28px;
  height: 28px;
  margin-top: 0.15rem;
  color: var(--colour-red);
}

.gate__title {
  margin: 0 0 0.25rem;
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
}

.gate__sub {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--colour-body);
}

.gate .btn { flex: none; }

.gate__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

@media (min-width: 480px) {
  .gate__actions { flex-direction: row; }
}


/* ==========================================================================
   22. Conversion upgrade
   Free first document offer, honest trust signals, sample document,
   signup context and the free-document dashboard state.
   ========================================================================== */

/* --- Hero offer -------------------------------------------------------------
   The free first document is the primary hook, so it sits above the headline.
   Red-dark text on the red tint is 5.8:1, clear of AA at this size.
   --------------------------------------------------------------------------- */

.hero__offer {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 var(--space-md);
  padding: 0.4rem 0.95rem 0.4rem 0.45rem;
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.3);
  border-radius: 999px;
  color: var(--colour-red-dark);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.3;
}

.hero__offer-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--colour-red);
  color: var(--colour-white);
}

.hero__offer-icon .icon { width: 16px; height: 16px; }

/* Price, surfaced in the hero. It used to first appear five screens down. */
.hero__price {
  margin: var(--space-md) 0 0;
  font-size: 0.9375rem;
  color: var(--colour-body);
}

.hero__price strong { color: var(--colour-ink); font-weight: 800; }

.hero__price + .hero__trust { margin-top: var(--space-xs); }


/* --- Trust strip -------------------------------------------------------------- */

.trust-strip {
  padding-block: var(--space-md);
  background: var(--colour-white);
  border-bottom: 1px solid var(--colour-grey-200);
}

.trust-strip__list {
  display: grid;
  gap: var(--space-sm);
}

@media (min-width: 900px) {
  .trust-strip__list {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg);
  }
}

.trust-strip__item {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.45;
  color: var(--colour-ink);
}

.trust-strip__item .icon {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 0.1rem;
  color: var(--colour-red);
}


/* --- Pricing assurances ------------------------------------------------------- */

.assurances {
  display: grid;
  gap: var(--space-sm);
  margin: 0 0 var(--space-xl);
}

@media (min-width: 760px) {
  .assurances { grid-template-columns: repeat(3, 1fr); }
}

.assurances__item {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: var(--space-sm) var(--space-md);
  background: var(--colour-grey);
  border: 1px solid var(--colour-grey-200);
  border-radius: var(--radius-md);
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--colour-body);
}

.assurances__item strong { color: var(--colour-ink); }

.assurances__item .icon {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 0.1rem;
  stroke-width: 3;
  color: var(--colour-green);
}

/* Reassurance right under each buy button. */
.plan__assure {
  margin: var(--space-sm) 0 0;
  font-size: 0.8125rem;
  text-align: center;
  color: var(--colour-body);
}


/* --- Dashboard: free first document panel -----------------------------------
   A gift, not a paywall. Stronger border than the gate panel so it reads as
   an invitation.
   --------------------------------------------------------------------------- */

.gift {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-lg);
  padding: var(--space-lg);
  background: linear-gradient(135deg, var(--colour-white) 0%, var(--colour-red-tint) 100%);
  border: 2px solid var(--colour-red);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

@media (min-width: 760px) {
  .gift {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.gift__body {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  min-width: 0;
}

.gift__badge {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--colour-red);
  color: var(--colour-white);
}

.gift__badge .icon { width: 26px; height: 26px; }

.gift__title {
  margin: 0 0 0.25rem;
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--colour-ink);
}

.gift__sub { margin: 0; color: var(--colour-body); }

.gift .btn { flex: none; }


/* --- Intake: free banner ------------------------------------------------------ */

.free-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 46rem;
  margin: 0 0 var(--space-lg);
  padding: 0.75rem 1rem;
  background: var(--colour-red-tint);
  border: 1px solid rgba(224, 30, 43, 0.3);
  border-radius: var(--radius-md);
  font-weight: 700;
  color: var(--colour-red-dark);
}

.free-banner .icon {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--colour-red);
}


/* --- Signup: what you clicked ------------------------------------------------- */

.signup-context {
  display: grid;
  gap: 0.2rem;
  margin: 0 0 var(--space-md);
  padding: 0.8rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  line-height: 1.45;
}

.signup-context strong {
  font-size: 1rem;
  font-weight: 800;
  color: var(--colour-ink);
}

.signup-context span {
  font-size: 0.875rem;
  color: var(--colour-body);
}

.signup-context--free {
  background: var(--colour-red-tint);
  border-color: rgba(224, 30, 43, 0.3);
}

.signup-context--plan {
  background: var(--colour-grey);
  border-color: var(--colour-grey-200);
}


/* --- Footer ABN ---------------------------------------------------------------- */

.footer__abn {
  margin: 0.35rem 0 0;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--colour-grey-400);
}


/* --- Sample document: real text in place of grey placeholder bars ------------
   Everything stays in em, so the one font-size dial on .doc-mock still scales
   the whole document together.
   --------------------------------------------------------------------------- */

.doc-mock__value {
  display: block;
  font-size: 0.78em;
  font-weight: 600;
  line-height: 1.3;
  color: var(--colour-ink);
}

.doc-mock__row--text { align-items: flex-start; }

.doc-mock__text {
  display: grid;
  gap: 0.15em;
  min-width: 0;
  font-size: 0.72em;
  line-height: 1.35;
  color: var(--colour-body);
}

.doc-mock__text strong {
  font-size: 1.08em;
  font-weight: 700;
  color: var(--colour-ink);
}

.doc-mock__signline {
  display: grid;
  gap: 0.45em;
}

/* Marks the mockup as an illustration, not a real client document. */
.doc-mock__watermark {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translate(-50%, -50%) rotate(-18deg);
  font-size: 3.6em;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(17, 17, 17, 0.06);
  pointer-events: none;
  user-select: none;
}


/* ==========================================================================
   23. Utilities

   Deliberately last in the file. These are the lowest level rules and they
   need to win against component styling, which source order gives them
   without reaching for !important.
   ========================================================================== */

/* The browser's own [hidden] rule lives in the UA stylesheet, which ANY author
   `display` declaration outranks. So `el.hidden = true` silently did nothing
   to components declared display:grid or display:flex, and the dashboard
   rendered its empty state and its request list at the same time.

   This rule restores the expected behaviour everywhere at once, instead of
   patching each component as the bug turns up in it.

   Specificity note: this is (0,1,0), the same as a single class, and it is
   last, so it beats plain component rules. Anything that genuinely needs to
   stay visible while carrying [hidden] just needs to be more specific, which
   is exactly what `.primary-nav[hidden]` at (0,2,0) does in the desktop nav
   block above. That override is intentional and still works.

   No !important: it would break that nav override and leave no escape hatch. */
[hidden] { display: none; }
