/* ==========================================================================
   Motor Spare Parts Shop Website — the six themes
   --------------------------------------------------------------------------
   One class on <html> selects one of these. Every theme draws the SAME
   markup: nothing in resources/views/sections/ knows which theme is running,
   and no theme adds or removes an element. That is the whole arrangement,
   and it is why six looks cost about as much as one. Immersive is the one
   narrow exception: it may add a canvas behind the banner. The canvas is
   additive and never load bearing, so remove it and the markup rule holds.

   Each block does two things:
     1. redefines the tokens in site.css, which is most of the work
     2. adds the handful of rules that give it a personality

   Rules to keep if you add a sixth:
     * define it for light AND dark. Every one of these is a real
       combination, and a customer with a dark phone will see it.
     * anything that moves goes behind prefers-reduced-motion. site.css
       already switches off transitions, fixed backgrounds and the reveal
       animation globally, so a theme must not introduce motion by any
       other route.
     * it has to be readable at 400px wide with no sideways scroll.

     1. Classic    — clean corporate, generous white space, soft cards
     2. Parallax   — layered fixed backgrounds, big display type, reveals
     3. Glass      — frosted cards over a soft gradient, blurred header
     4. Bold       — heavy display type and full width colour blocks
     5. Editorial  — a wide measure, a lead item and rules instead of boxes
     6. Immersive  — near black, one huge headline, the stock turning in 3D

   All six are set in ROBOTO, which the product ships as one variable file.
   Two of them used not to be: Classic was Georgia and Editorial was Palatino
   with small capitals and a drop cap, and both read as a website from the
   early two thousands however good the words on them were. A theme's
   personality here comes from weight, scale, space and colour, never from
   dressing the page up as a period. ========================================= */

/* ==========================================================================
   1. Classic
   --------------------------------------------------------------------------
   The safe one. A law firm, a wholesaler, a customs agent. Nothing moves
   except the reveal fade and a card lifting under the pointer, and the space
   between bands is the loudest thing on the page.
   ========================================================================== */

.theme-classic {
  /* Roboto, like every theme here. This one used to be set in Georgia with
     a three pixel brand rule under each heading and six pixel corners, which
     is a look that dates a page to about 2004 however good the words are.
     The restraint is kept and the period costume is not: the personality now
     comes from space, weight and one clean accent. */
  --head-weight: 700;
  --head-tracking: -0.022em;
  --head-line: 1.12;
  --h1: clamp(2.25rem, 5vw, 3.6rem);
  --h2: clamp(1.65rem, 3.2vw, 2.4rem);

  --band-y: 6rem;
  --radius: 12px;
  --radius-lg: 18px;

  --card-shadow: var(--shadow-sm);
  --card-border: 1px solid var(--line);

  --hero-min: 64vh;
}

/* Classic's hero is LIGHT by default. Ink on paper, not text on a
   photograph, and the veil only appears when there is something behind it
   to darken. A soft wash of the buyer's own colour across the top, rather
   than a flat grey slab. */
.theme-classic .hero {
  background:
    radial-gradient(1100px 520px at 12% -20%, rgba(var(--brand-rgb), .14), transparent 62%),
    radial-gradient(900px 480px at 92% 0%, rgba(var(--accent-rgb), .1), transparent 60%),
    var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.theme-classic .hero__art { opacity: .16; }

.theme-classic .card:hover { border-color: var(--line-strong); }
.theme-classic .quote { border-inline-start: 3px solid var(--brand); }

.theme-classic .site-head { box-shadow: none; }

html[data-theme="dark"].theme-classic {
  --surface-2: #151e2d;
  --surface-3: #1d2839;
}

/* ==========================================================================
   2. Parallax
   --------------------------------------------------------------------------
   Layers. The hero picture and the numbers band are fixed to the viewport so
   the page scrolls over them, and everything arrives with a fade. All of it
   is CSS plus one IntersectionObserver, and all of it is off under
   prefers-reduced-motion.
   ========================================================================== */

.theme-parallax {
  --head-weight: 800;
  --head-tracking: -0.035em;
  --head-line: 1.03;
  --h1: clamp(2.4rem, 6.4vw, 4.2rem);
  --h2: clamp(1.7rem, 3.8vw, 2.6rem);

  --band-y: 6rem;
  --radius: 14px;
  --radius-lg: 22px;

  --dark-bg: #070c16;
  --card-shadow: var(--shadow);

  --hero-min: 88vh;
}

/* The two fixed layers. background-attachment is the whole parallax: no
   scroll handler, no transform on scroll, nothing that can drop a frame. */
.theme-parallax .hero,
.theme-parallax .hero__art,
.theme-parallax .band--stats {
  background-attachment: fixed;
}

/* Parallax's hero is DARK whether or not a photograph was uploaded, so
   the artwork can be drawn at full strength. The ink has to be switched
   with it: site.css only lights the type when there is a real picture,
   and a theme that darkens the panel itself owns that decision. */
.theme-parallax .hero {
  background-color: #0a1120;
  color: var(--ink-on-dark);
}
.theme-parallax .hero h1,
.theme-parallax .hero .hero__sub,
.theme-parallax .hero p { color: var(--ink-on-dark); }
.theme-parallax .hero .eyebrow { color: #ffffff; opacity: .8; }
.theme-parallax .hero .btn--outline { border-color: rgba(255, 255, 255, .5); color: #fff; }
.theme-parallax .hero__art { opacity: .6; }

/* A hero this tall with a picture behind it needs a heavier veil at the
   bottom, or the first line of the section below reads through it.

   And a second gradient across it, weighted to the START edge, because this
   theme overrode site.css's veil entirely and got back a wash that is even
   left to right: the scent studio's headline ran over a lit glass flask and
   the last two words went pale. The vertical pass still does the work at the
   bottom; this one only has to hold the side the words are on. */
.theme-parallax .hero__veil {
  background:
    linear-gradient(100deg, rgba(6, 10, 20, .62) 0%, rgba(6, 10, 20, .34) 46%, rgba(6, 10, 20, 0) 78%),
    linear-gradient(180deg, rgba(6, 10, 20, .5) 0%, rgba(6, 10, 20, .34) 40%, rgba(6, 10, 20, .88) 100%);
}

/* Two soft out of focus shapes behind the hero text. Decorative, so they
   are drawn by the theme rather than sitting in the markup. */
.theme-parallax .hero::before,
.theme-parallax .hero::after {
  content: "";
  position: absolute;
  z-index: 1;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
}
.theme-parallax .hero::before {
  width: 42vw; height: 42vw;
  left: -8vw; top: -12vw;
  background: rgba(var(--brand-rgb), .5);
}
.theme-parallax .hero::after {
  width: 34vw; height: 34vw;
  right: -6vw; bottom: -14vw;
  background: rgba(var(--accent-rgb), .38);
}

.theme-parallax .band--alt {
  background:
    radial-gradient(1200px 400px at 12% -10%, rgba(var(--brand-rgb), .12), transparent 60%),
    var(--surface-2);
}

/* Further travel on the reveal than the other themes, because this one is
   about arrival. Still the same class, still armed by the same script, and
   still switched off with everything else under reduced motion. */
.theme-parallax .reveal.is-armed { transform: translateY(40px) scale(.995); }

.theme-parallax .card { border-width: 1px; }
.theme-parallax .card:hover { transform: translateY(-4px); }
.theme-parallax .btn--brand { box-shadow: 0 10px 30px rgba(var(--brand-rgb), .35); }
.theme-parallax .icon-tile {
  background: linear-gradient(140deg, var(--brand), var(--accent));
  color: var(--brand-ink);
}
.theme-parallax .stat__value { text-shadow: 0 4px 22px rgba(0, 0, 0, .25); }

html[data-theme="dark"].theme-parallax {
  --bg: #070c16;
  --surface: #0f1726;
  --surface-2: #0b1220;
  --surface-3: #16202f;
}

/* ==========================================================================
   3. Glass
   --------------------------------------------------------------------------
   Frosted panels over a gradient that stays put. The gradient is on a fixed
   pseudo element rather than on the body, so it cannot be scrolled off and
   cannot stretch on a long page.
   ========================================================================== */

.theme-glass {
  --radius: 18px;
  --radius-lg: 26px;
  --band-y: 4.8rem;

  --head-weight: 700;
  --head-tracking: -0.025em;

  --bg: #eef2fa;
  --surface: #ffffff;
  --surface-2: rgba(255, 255, 255, .45);
  --surface-3: rgba(255, 255, 255, .55);
  --line: rgba(120, 140, 180, .28);
  --line-strong: rgba(120, 140, 180, .45);

  --card-bg: rgba(255, 255, 255, .55);
  --card-border: 1px solid rgba(255, 255, 255, .7);
  --card-shadow: 0 12px 40px rgba(34, 52, 90, .13);
  --card-blur: blur(16px) saturate(140%);

  --hero-min: 76vh;
}

.theme-glass body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(900px 620px at 8% 0%, rgba(var(--brand-rgb), .38), transparent 62%),
    radial-gradient(760px 560px at 96% 12%, rgba(var(--accent-rgb), .3), transparent 60%),
    radial-gradient(900px 700px at 50% 110%, rgba(var(--brand-rgb), .22), transparent 62%),
    var(--bg);
}

.theme-glass .site-head {
  background: rgba(255, 255, 255, .58);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-bottom: 1px solid rgba(255, 255, 255, .6);
}

/* Bands are see through, so the gradient behind the page is the background
   of every one of them. */
.theme-glass .band--alt,
.theme-glass .page-hero { background: transparent; }
.theme-glass .page-hero { border-bottom: 1px solid var(--line); }

.theme-glass .hero { background: transparent; }
.theme-glass .hero__veil { display: none; }
.theme-glass .hero__art { opacity: .5; mix-blend-mode: soft-light; }

/* The hero text sits on a panel of its own, which is what makes the theme
   legible over whatever gradient or picture is behind it. */
/* The panel the hero words sit on.
   Raised from half opaque to two thirds, and the blur with it, after looking
   at it over a real photograph for the first time: a salon interior with
   lamps and shelving behind the heading came through the frost as mottling,
   and dark ink over mottling is legible in the way a fax is legible. Every
   Glass product with a busy hero picture had the same problem; the pale
   gradient the theme ships with hid it. */
.theme-glass .hero__content {
  padding: 2.2rem;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .68);
  border: 1px solid rgba(255, 255, 255, .78);
  box-shadow: 0 20px 60px rgba(34, 52, 90, .18);
  backdrop-filter: blur(24px) saturate(150%);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
}
/* The panel is light, so the hero ink stays dark even with a picture
   behind it. on-dark is undone here on purpose. */
.theme-glass .hero.on-dark,
.theme-glass .hero.on-dark h1,
.theme-glass .hero.on-dark .hero__sub,
.theme-glass .hero.on-dark p { color: var(--ink); }
.theme-glass .hero.on-dark .hero__sub, .theme-glass .hero.on-dark p { color: var(--ink-2); }
.theme-glass .hero.on-dark .eyebrow { color: var(--brand-fg); opacity: 1; }
.theme-glass .hero.on-dark .btn--outline { border-color: var(--line-strong); color: var(--ink); }

.theme-glass .input, .theme-glass .textarea, .theme-glass .select {
  background: rgba(255, 255, 255, .6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.theme-glass .card:hover { transform: translateY(-3px); box-shadow: 0 18px 50px rgba(34, 52, 90, .2); }
.theme-glass .band--stats {
  background: rgba(var(--brand-rgb), .82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.theme-glass .band--cta {
  background: rgba(14, 21, 34, .78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.theme-glass .site-foot { background: rgba(10, 16, 28, .88); backdrop-filter: blur(14px); }

html[data-theme="dark"].theme-glass {
  --bg: #080d18;
  --surface: #131c2b;
  --surface-3: rgba(255, 255, 255, .06);
  --line: rgba(255, 255, 255, .14);
  --line-strong: rgba(255, 255, 255, .24);

  --card-bg: rgba(20, 30, 46, .6);
  --card-border: 1px solid rgba(255, 255, 255, .12);
  --card-shadow: 0 14px 44px rgba(0, 0, 0, .5);
}
html[data-theme="dark"].theme-glass .site-head {
  background: rgba(13, 20, 32, .6);
  border-bottom-color: rgba(255, 255, 255, .1);
}
html[data-theme="dark"].theme-glass .hero__content {
  background: rgba(20, 30, 46, .74);
  border-color: rgba(255, 255, 255, .12);
  box-shadow: 0 24px 64px rgba(0, 0, 0, .55);
}
html[data-theme="dark"].theme-glass .input,
html[data-theme="dark"].theme-glass .textarea,
html[data-theme="dark"].theme-glass .select { background: rgba(255, 255, 255, .07); }

/* Not every browser has backdrop-filter, and a translucent panel with no
   blur behind it is unreadable. Where it is missing, the panels become
   solid. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .theme-glass {
    --card-bg: #ffffff;
    --card-border: 1px solid rgba(120, 140, 180, .3);
  }
  .theme-glass .site-head { background: #ffffff; }
  .theme-glass .hero__content { background: rgba(255, 255, 255, .94); }
  html[data-theme="dark"].theme-glass { --card-bg: #141d2c; }
  html[data-theme="dark"].theme-glass .site-head { background: #0d1420; }
  html[data-theme="dark"].theme-glass .hero__content { background: rgba(19, 28, 43, .96); }
}

/* ==========================================================================
   4. Bold
   --------------------------------------------------------------------------
   Heavy uppercase type, square corners, thick borders, and every other band
   is a full width block of the brand colour. For a gym, an event company or
   anything selling energy.
   ========================================================================== */

.theme-bold {
  /* Roboto at 900, which is a real drawn weight on the variable face rather
     than Helvetica pretending.

     Two changes of substance. The uppercase was GLOBAL, so every card title
     and every question on the FAQ was shouted as well as the headline, and a
     page of uppercase sentences is unreadable before it is dated — it is now
     on the headline and the kicker only. And the corners were hard zero
     everywhere, which was a 2016 brutalist tic; eight pixels keeps the
     squareness without the period. */
  --head-weight: 900;
  --head-transform: none;
  --head-tracking: -0.035em;
  --head-line: .96;
  --h1: clamp(2.6rem, 8.4vw, 5.4rem);
  --h2: clamp(1.9rem, 4.8vw, 3.1rem);
  --h3: 1.24rem;

  --radius: 8px;
  --radius-lg: 10px;
  --radius-pill: 8px;
  --band-y: 5.5rem;

  --card-bg: var(--surface);
  --card-border: 2px solid var(--ink);
  --card-shadow: none;

  --line: #1a1f29;
  --line-strong: #1a1f29;
  --dark-bg: #101319;

  /* This theme's buttons are heavier: more padding and a 3px border, which
     comes out at 48.5px. The header's icon buttons follow, or the switch
     beside the call to action is ten pixels shorter than it. */
  --ctl-h: 48px;

  --hero-min: 80vh;
}

/* The headline and the kicker are the two places this theme shouts. */
.theme-bold .hero h1,
.theme-bold .page-hero h1 { text-transform: uppercase; }

.theme-bold .site-head { border-bottom: 2px solid var(--ink); }

/* The colour block. Redefining the ink tokens inside the band is what
   carries the change down to every heading, paragraph and card in it,
   without a single extra class in the markup. */
.theme-bold .band--alt {
  background: var(--brand);
  --ink: var(--brand-ink);
  --ink-2: var(--brand-ink);
  --ink-3: var(--brand-ink);
  --line: var(--brand-ink);
  --line-strong: var(--brand-ink);
  --card-bg: transparent;
  --card-border: 2px solid var(--brand-ink);
  color: var(--brand-ink);
}
.theme-bold .band--alt .eyebrow { color: var(--brand-ink); opacity: .8; }
.theme-bold .band--alt .icon-tile { background: rgba(255, 255, 255, .16); color: var(--brand-ink); }
.theme-bold .band--alt .btn--brand { background: var(--brand-ink); border-color: var(--brand-ink); color: var(--brand); }
.theme-bold .band--alt .text-link { color: var(--brand-ink); text-decoration: underline; }
.theme-bold .band--alt .chip { background: rgba(255, 255, 255, .18); color: var(--brand-ink); }
/* The other half of the same rule, and it was missing. The block IS the
   brand colour, so anything site.css draws IN the brand colour disappears
   into it: the opening quote mark, the initial in an avatar, the chevron
   that is the only sign a question opens, and the icon beside every line of
   the address. Measured at 1.00:1, which is not faint, it is absent, and no
   test can see it. The required field asterisk is the same problem from the
   other direction: a dark red on magenta. */
.theme-bold .band--alt .quote__mark { color: var(--brand-ink); opacity: .6; }
.theme-bold .band--alt .avatar { background: rgba(255, 255, 255, .2); color: var(--brand-ink); }
.theme-bold .band--alt .faq__q svg,
.theme-bold .band--alt .detail-list svg { color: var(--brand-ink); }
.theme-bold .band--alt .person__role { color: var(--brand-ink); }
.theme-bold .band--alt .label__req { color: var(--brand-ink); }
.theme-bold .band--alt a.card:hover .card__title { color: var(--brand-ink); }

.theme-bold .btn {
  border-width: 2px;
  border-color: var(--ink);
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  font-size: .86rem;
  padding: .8rem 1.5rem;
  box-shadow: none;
}
.theme-bold .btn--brand { border-color: var(--brand); box-shadow: none; }
/* The hard offset shadow is this theme's signature and it is still a
   current look. It moves on hover rather than sitting there, which is the
   part that makes it read as deliberate. */
.theme-bold .btn:hover { transform: translate(-2px, -2px); box-shadow: 4px 4px 0 var(--ink); }
.theme-bold .band--alt .btn:hover { box-shadow: 4px 4px 0 var(--brand-ink); }

.theme-bold .card:hover { transform: translate(-3px, -3px); box-shadow: 6px 6px 0 var(--brand); }
/* --head-line is under one for the display sizes, which is right for a hero
   and far too tight for a two line card title, where the lines touch. */
.theme-bold .card__title, .theme-bold h3 { line-height: 1.16; }
.theme-bold .band__head { max-width: 900px; }
.theme-bold .eyebrow { --tracking: .2em; }
/* Same arrangement as Parallax: the panel is dark by the theme's own
   decision, so the theme lights the ink rather than leaving it to the
   picture that may not be there. */
.theme-bold .hero {
  background-color: #10131a;
  color: var(--ink-on-dark);
}
.theme-bold .hero h1,
.theme-bold .hero .hero__sub,
.theme-bold .hero p { color: var(--ink-on-dark); }
.theme-bold .hero .eyebrow { color: var(--accent); opacity: 1; }
.theme-bold .hero .btn { border-color: #ffffff; }
/* The outline button needs its INK lit as well as its border. On a hero
   this theme darkened itself, `on-dark` is not applied (there is no
   photograph), so the base rule leaves the wording in page ink and the
   button reads as an empty box. */
.theme-bold .hero .btn--outline { color: #ffffff; }
.theme-bold .hero .btn--outline:hover { background: rgba(255, 255, 255, .14); }
/* And the same everywhere else the ink goes light. `.theme-bold .btn` sets
   every border to --ink, which outranks site.css's on-dark rule, so on the
   call to action band the secondary button was drawn with a near black ring
   on the brand colour while its wording was white. The hero had been fixed;
   nothing else had. */
.theme-bold .on-dark .btn--outline { border-color: #ffffff; color: #ffffff; }
.theme-bold .on-dark .btn--outline:hover { background: rgba(255, 255, 255, .14); box-shadow: 4px 4px 0 #ffffff; }
/* The primary button on this theme's dark hero keeps the WHITE border the
   rule above gives it. It used to be handed its brand colour back here,
   which is fine for a bright brand and invisible for a dark one: the
   photography studio's near black button sat on a near black hero with no
   edge at all, so the secondary outlined button read as the main action and
   the main action read as nothing. */
.theme-bold .hero .btn:hover { box-shadow: 4px 4px 0 #ffffff; }
.theme-bold .hero__art { opacity: .42; }
.theme-bold .hero__veil { background: linear-gradient(90deg, rgba(10, 13, 20, .9), rgba(10, 13, 20, .45)); }
.theme-bold .stat__value { font-size: clamp(2.4rem, 7vw, 4rem); }
.theme-bold .quote { border: 2px solid var(--ink); }
.theme-bold .faq { border-bottom-width: 2px; }
.theme-bold .faq:first-child { border-top-width: 2px; }


html[data-theme="dark"].theme-bold {
  --line: #eef1f6;
  --line-strong: #eef1f6;
  --card-border: 2px solid var(--ink);
  --surface: #131823;
  --surface-2: #0d1218;
}

/* ==========================================================================
   5. Editorial
   --------------------------------------------------------------------------
   A magazine. Serif throughout, rules instead of cards, small capitals on
   the meta lines, an opening letter on an article, and a lead item that is
   twice the width of the others. Built for the sites that are mostly words:
   a school, a council, a news desk.
   ========================================================================== */

.theme-editorial {
  /* Roboto here too. This was a Palatino pastiche with small capitals and a
     drop cap, which is a magazine from 1998 rather than a masthead anybody
     reads now. What made it worth keeping is STRUCTURE, not ornament: a wide
     measure, a strong lead item, and rules instead of boxes. Those stay.
     Tall, tightly tracked headlines do the work the serif used to. */
  --head-weight: 800;
  --head-tracking: -0.03em;
  --head-line: 1.06;
  --h1: clamp(2.4rem, 6vw, 4.2rem);
  --h2: clamp(1.75rem, 3.6vw, 2.6rem);
  --body-size: 17px;
  --body-line: 1.75;

  --radius: 8px;
  --radius-lg: 10px;
  --band-y: 4.6rem;

  --card-bg: transparent;
  --card-border: 0;
  --card-shadow: none;

  /* Paper, not parchment. The old set was a yellowed cream that read as an
     old newspaper; this is a neutral warm white that still separates from
     pure white cards and photographs. */
  --bg: #fcfcfb;
  --surface: #fcfcfb;
  --surface-2: #f4f4f2;
  --surface-3: #e9e9e6;
  --line: #e0e0dc;
  --line-strong: #b9b9b3;
  --dark-bg: #14140f;

  --hero-min: 60vh;
}

.theme-editorial .site-head { border-bottom: 1px solid var(--ink); }

/* Rules, not tints. The alternating band is marked by lines above and
   below it rather than by a change of colour. */
.theme-editorial .band--alt {
  background: transparent;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.theme-editorial .band__head {
  border-bottom: 1px solid var(--ink);
  padding-bottom: 1rem;
  max-width: none;
}
/* The kicker stays a kicker: uppercase, tracked, in the brand colour. The
   small capitals it used to be set in are a serif mannerism that Roboto has
   no business imitating — a sans faking small caps is a synthesised look,
   and browsers draw it by shrinking capitals, which is the wrong shape. */
.theme-editorial .eyebrow { --tracking: .18em; font-size: .72rem; }

/* A card is a column of type under a hairline, which is what a magazine
   page actually looks like. */
.theme-editorial .card { border-top: 1px solid var(--line); border-radius: 0; }
.theme-editorial .card__body { padding: 1.1rem 0 1.4rem; }
.theme-editorial .card__foot { padding: 0 0 1.4rem; }
.theme-editorial .card__meta {
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .72rem;
  font-weight: 600;
}
.theme-editorial .card__title { font-size: 1.35rem; letter-spacing: -.025em; }
/* A magazine column does not lift off the page, so the card stays put and
   the RULE above it darkens instead. Something has to answer the pointer, or
   a grid of headlines reads as a picture of a page rather than a page. */
.theme-editorial .card:hover {
  transform: none;
  box-shadow: none;
  border-top-color: var(--ink);
}
.theme-editorial .cover { border-radius: 0; }

/* The lead item is twice as wide, which is the one structural difference
   any of the five themes makes. It is a grid span, so it reflows to a
   single column with everything else on a narrow screen. */
@media (min-width: 900px) {
  .theme-editorial .grid--lead { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .theme-editorial .grid--lead > *:first-child { grid-column: span 2; }
  .theme-editorial .grid--lead > *:first-child .card__title { font-size: 1.9rem; }
  .theme-editorial .grid--lead > *:first-child .cover { aspect-ratio: 21 / 9; }
}

/* The standfirst: the first paragraph of an article is set larger and
   darker, which is how a masthead actually opens a piece now. It replaces
   the drop cap, which was the single most dated thing in these five themes
   and which this kernel drew on every article of every Editorial site. */
.theme-editorial .article__body > p:first-of-type {
  font-size: 1.24rem;
  line-height: 1.55;
  color: var(--ink);
  font-weight: 450;
}

.theme-editorial .hero { background: var(--surface-2); border-bottom: 1px solid var(--ink); }
/* Very faint: the shipped artwork is dark, and at a fifth it turned this
   theme's paper colour into a flat grey block that read as a different
   site above the fold. */
.theme-editorial .hero__art { opacity: .08; }
.theme-editorial .quote {
  border: 0;
  border-inline-start: 2px solid var(--ink);
  border-radius: 0;
  padding-block: .3rem;
  padding-inline: 1.4rem 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}
.theme-editorial .quote__text { font-size: 1.24rem; line-height: 1.45; letter-spacing: -.015em; }
.theme-editorial .page-hero { background: transparent; border-bottom: 1px solid var(--ink); }
/* The tinted tile from site.css is kept. It used to be a hollow box with a
   hairline round it, which is the 2015 pattern and read as an empty frame at
   this size. */
.theme-editorial .prose { max-width: 68ch; }

html[data-theme="dark"].theme-editorial {
  --bg: #14130f;
  --surface: #14130f;
  --surface-2: #1b1a15;
  --surface-3: #23211a;
  --line: #3a372c;
  --line-strong: #56513f;
  --ink: #f0ece0;
  --ink-2: #cdc7b6;
  --ink-3: #9c9585;
}

/* ==========================================================================
   6. Immersive
   --------------------------------------------------------------------------
   A shop where the products are the reason people came. A deep, near black
   page, one enormous headline, and the shop's own catalogue turning slowly
   behind the banner.

   This is the only theme that is dark in BOTH modes, and that is deliberate
   rather than an omission: photographs lifted off a near black page is the
   theme, and over a white one there is nothing for them to lift off. What the light and dark switch
   changes here is how far down it goes, not whether it is dark at all. A
   visitor whose phone is set to light still gets a designed page, not a
   half finished one.

   The canvas is additive and NEVER load bearing. public/js/hero3d.js is only
   loaded when the buyer has switched the banner on, it refuses to run
   without WebGL, and with it gone this is an ordinary dark theme with a
   gradient behind the banner. Nothing on the page depends on a graphics
   card.
   ========================================================================== */

.theme-immersive {
  --head-weight: 800;
  --head-tracking: -0.04em;
  --head-line: 1.0;
  --h1: clamp(2.6rem, 7vw, 5.2rem);
  --h2: clamp(1.8rem, 3.8vw, 2.8rem);
  --body-line: 1.7;

  --band-y: 6.5rem;
  --radius: 14px;
  --radius-lg: 22px;

  --ink: #eef1f6;
  --ink-2: #b7c0d0;
  --ink-3: #7d8899;

  --bg: #0b1018;
  --surface: #111825;
  --surface-2: #0e1420;
  --surface-3: #18202f;

  --line: #1e2839;
  --line-strong: #2d3a51;

  --card-bg: rgba(255, 255, 255, .035);
  --card-border: 1px solid rgba(255, 255, 255, .08);
  --card-shadow: 0 20px 60px rgba(0, 0, 0, .45);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .6);
  --shadow: 0 8px 26px rgba(0, 0, 0, .55);
  --shadow-lg: 0 24px 64px rgba(0, 0, 0, .7);

  --brand-fg: var(--brand-light);

  --hero-min: 88vh;

  color-scheme: dark;
}

@supports (color: color-mix(in srgb, #000 50%, #fff)) {
  .theme-immersive { --brand-fg: color-mix(in srgb, var(--brand) 46%, #ffffff); }
}

/* Dark mode goes further down rather than becoming a different theme. */
html[data-theme="dark"].theme-immersive {
  --bg: #05070d;
  --surface: #0b1018;
  --surface-2: #080c13;
  --surface-3: #121a27;
  --line: #18202e;
  --line-strong: #263146;
}

/* The banner. Two wide washes of the buyer's own colours, which is what the
   page shows when the canvas is off, refused or still downloading. */
.theme-immersive .hero {
  background:
    radial-gradient(1200px 700px at 78% 18%, rgba(var(--brand-rgb), .30), transparent 62%),
    radial-gradient(900px 620px at 14% 88%, rgba(var(--accent-rgb), .20), transparent 60%),
    var(--bg);
  border-bottom: 1px solid var(--line);
  position: relative;
  overflow: hidden;
}
.theme-immersive .hero__art { opacity: .10; }

/* The canvas layer. Behind the copy, above the washes, and invisible until
   the script says it has a context it can draw with. */
.theme-immersive .hero3d {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.4s cubic-bezier(.16, 1, .3, 1);
}
.theme-immersive .hero3d.is-ready { opacity: 1; }
.theme-immersive .hero3d canvas { display: block; width: 100%; height: 100%; }

/* The ring turns, so sooner or later a card swings across the headline
   whatever the geometry is set to. Tuning the offset only moves the
   moment it happens. Fading the canvas out over the text column settles
   it once: the copy is always clear and the cards appear to come out of
   the page rather than being cut off at an edge. */
.theme-immersive .hero3d {
  -webkit-mask-image: linear-gradient(to right, transparent 4%, rgba(0,0,0,.35) 26%, #000 46%);
  mask-image: linear-gradient(to right, transparent 4%, rgba(0,0,0,.35) 26%, #000 46%);
}
[dir="rtl"] .theme-immersive .hero3d {
  -webkit-mask-image: linear-gradient(to left, transparent 4%, rgba(0,0,0,.35) 26%, #000 46%);
  mask-image: linear-gradient(to left, transparent 4%, rgba(0,0,0,.35) 26%, #000 46%);
}

/* On a phone the copy is at the top and the ring sits underneath it, so
   the fade runs the other way. */
@media (max-width: 768px) {
  .theme-immersive .hero3d,
  [dir="rtl"] .theme-immersive .hero3d {
    -webkit-mask-image: linear-gradient(to bottom, transparent 10%, #000 42%);
    mask-image: linear-gradient(to bottom, transparent 10%, #000 42%);
  }
}

/* Once the real thing is drawing, pull the shipped artwork back so the two
   are not competing for the same space. */
.theme-immersive .hero:has(.hero3d.is-ready) .hero__art { opacity: .03; }

/* Nothing else in the banner needs a position or a z-index here.
   site.css already gives .hero__inner `position: relative; z-index: 2`,
   and .hero__veil is `position: absolute; inset: 0` - setting that to
   relative collapses it to nothing and takes the darkening out from
   behind the headline, which looks like the veil was never rendered.
   The canvas sits at z-index 0 and everything above it is left alone. */

.theme-immersive .hero h1 {
  text-wrap: balance;
}

.theme-immersive .hero__sub {
  max-width: 46ch;
  color: var(--ink-2);
}

/* A hairline of the brand colour along the top of every band, which is what
   separates sections on a page with no white space to do it. */
.theme-immersive .band--alt {
  background: linear-gradient(180deg, rgba(var(--brand-rgb), .07), transparent 40%),
              var(--surface-2);
}

.theme-immersive .site-head {
  background: rgba(8, 12, 19, .72);
  border-bottom: 1px solid var(--line);
}
@supports (backdrop-filter: blur(1px)) {
  .theme-immersive .site-head { backdrop-filter: saturate(150%) blur(14px); }
}

.theme-immersive .card {
  transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease;
}
.theme-immersive .card:hover {
  border-color: rgba(var(--brand-rgb), .45);
  box-shadow: 0 0 0 1px rgba(var(--brand-rgb), .18), var(--card-shadow);
}

/* The section header on a catalogue page: the same showcase, shorter,
   so a category reads as part of the same shop rather than a plain list. */
.theme-immersive .page-hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(900px 420px at 82% 10%, rgba(var(--brand-rgb), .24), transparent 62%),
    radial-gradient(700px 360px at 10% 95%, rgba(var(--accent-rgb), .16), transparent 60%),
    var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.theme-immersive .page-hero .hero3d { z-index: 0; }
.theme-immersive .page-hero > .wrap { position: relative; z-index: 1; }

/* Nothing here introduces motion of its own, so there is nothing for this
   to switch off - but the canvas is the exception the rule was written for,
   and the script draws a single still frame under the same query. Kept so
   the next person does not have to go and check. */
@media (prefers-reduced-motion: reduce) {
  .theme-immersive .hero3d { transition: none; }
  .theme-immersive .card { transition: none; }
}

@media (max-width: 720px) {
  .theme-immersive { --hero-min: 76vh; --band-y: 4.4rem; }
}
