/* ═══════════════════════════════════════════════════════════════════════════
   GLAZING SERVICES — "light through glass"

   The client sells glass, so the interface is made of it: frosted panes over a
   dark ground with light blooming behind them, and a bright refracted edge
   where the light catches a pane. The 45° lattice in the background is lifted
   from the logo.

   Written against the EXISTING markup so nothing had to be rewritten to adopt
   it — site.css is still in the repo, so swapping the <link> back reverts the
   whole site.

   Three capabilities carry it, all recent enough to be worth naming:
     backdrop-filter     real frosted glass
     animation-timeline  scroll reveals with no JavaScript
     @view-transition    pages cross-fade instead of white-flashing

   ⚠ Never put .reveal on anything above the fold. An element already on screen
   at load sits BEFORE the start of a view() range, so it renders at opacity 0
   and never appears. It fails silently and looks like a missing component.
   ═══════════════════════════════════════════════════════════════════════════ */

@view-transition { navigation: auto; }

/* ── fonts ─────────────────────────────────────────────────────────────── */
@font-face{font-family:'Schibsted Grotesk';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/schibsted-400.woff2') format('woff2')}
@font-face{font-family:'Schibsted Grotesk';font-style:normal;font-weight:500;font-display:swap;
  src:url('/assets/fonts/schibsted-500.woff2') format('woff2')}
@font-face{font-family:'Schibsted Grotesk';font-style:normal;font-weight:600;font-display:swap;
  src:url('/assets/fonts/schibsted-600.woff2') format('woff2')}
@font-face{font-family:'Schibsted Grotesk';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/schibsted-700.woff2') format('woff2')}
@font-face{font-family:'Schibsted Grotesk';font-style:normal;font-weight:800;font-display:swap;
  src:url('/assets/fonts/schibsted-800.woff2') format('woff2')}

:root{
  --ink:#0B1516;
  --deep:#123138;
  --sky:#5FA8B0;
  --bright:#8FD3DA;
  --text:#E8F1F1;
  --muted:#B4CCCE;
  --faint:#7C9799;
  --pane:linear-gradient(150deg,rgba(255,255,255,.115),rgba(255,255,255,.045) 46%,rgba(255,255,255,.02));
  --edge:rgba(255,255,255,.14);
  --edge-soft:rgba(255,255,255,.09);
  --font:'Schibsted Grotesk',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  font-family:var(--font); background:var(--ink); color:var(--text);
  line-height:1.65; overflow-x:hidden; position:relative; isolation:isolate;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
:focus-visible{outline:2px solid var(--bright);outline-offset:3px;border-radius:4px}

/* ── the ground: a fixed light bloom + the logo lattice ─────────────────── */
body::before{
  content:"";position:fixed;inset:-20%;z-index:-2;pointer-events:none;
  background:
    radial-gradient(52% 42% at 20% 6%, rgba(143,211,218,.30), transparent 62%),
    radial-gradient(46% 46% at 84% 24%, rgba(95,168,176,.19), transparent 60%),
    radial-gradient(60% 50% at 50% 98%, rgba(18,49,56,.85), transparent 70%),
    linear-gradient(170deg,#0E2126 0%,#0B1516 58%);
}
body::after{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.5;
  background:
    linear-gradient(115deg,transparent 38%,rgba(255,255,255,.045) 38%,rgba(255,255,255,.045) 43%,transparent 43%),
    linear-gradient(115deg,transparent 63%,rgba(255,255,255,.03) 63%,rgba(255,255,255,.03) 66%,transparent 66%);
}

.wrap{max-width:1120px;margin:0 auto;padding:0 22px}

/* ── the pane: one component everything else is built from ─────────────── */
.pane,
.quote-card, .service, .why-item, .review, .svc-card, .shot, .rel,
.creds-item, .area-band, .svc-body, details{
  position:relative;
  background:var(--pane);
  backdrop-filter:blur(20px) saturate(140%);
  -webkit-backdrop-filter:blur(20px) saturate(140%);
  border:1px solid var(--edge);
  border-radius:18px;
  box-shadow:0 1px 0 rgba(255,255,255,.2) inset, 0 22px 56px -30px rgba(0,0,0,.9);
}
/* the refracted edge */
.pane::before, .quote-card::before, .service::before, .review::before,
.svc-card::before, .svc-body::before{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(150deg,rgba(255,255,255,.45),transparent 26%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;padding:1px;
}

/* ── typography ────────────────────────────────────────────────────────── */
h1,h2,h3,h4{text-wrap:balance;color:#fff;letter-spacing:-.025em;line-height:1.14}
h1{font-weight:800;letter-spacing:-.04em;line-height:1}
p{color:var(--muted)}

/* ── header ────────────────────────────────────────────────────────────── */
header.site{
  position:sticky;top:0;z-index:50;
  background:rgba(11,21,22,.58);
  backdrop-filter:blur(18px) saturate(150%);-webkit-backdrop-filter:blur(18px) saturate(150%);
  border-bottom:1px solid var(--edge-soft);
}
header.site .wrap{display:flex;align-items:center;justify-content:space-between;height:68px;gap:16px}
.brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:18px;color:#fff;letter-spacing:-.015em}
.brand .mark{width:34px;height:34px}
.brand-text{display:flex;flex-direction:column;line-height:1.1}
.brand-text small{font-size:9.5px;font-weight:600;color:var(--sky);letter-spacing:.09em;
  text-transform:uppercase;margin-top:2px}
nav.links{display:none;gap:24px;font-weight:500;font-size:15px;color:#C7DEE0}
nav.links a:hover{color:#fff}
@media(min-width:940px){nav.links{display:flex;align-items:center}}
.top-actions{display:flex;align-items:center;gap:13px}
.top-phone{font-weight:700;color:#fff;font-size:17px;display:none}
.top-phone small{display:block;font-size:10.5px;font-weight:600;color:var(--faint);letter-spacing:.05em}
@media(min-width:1040px){.top-phone{display:block}}
.nav-cta,.callbtn{
  padding:10px 18px;border-radius:11px;font-weight:700;font-size:15px;color:#062024;
  background:linear-gradient(160deg,var(--bright),var(--sky));
  box-shadow:0 8px 22px -10px rgba(143,211,218,.7);
}

/* services dropdown */
.menu{position:relative}
.menu-btn{background:none;border:0;font:inherit;font-weight:500;font-size:15px;color:#C7DEE0;
  cursor:pointer;display:flex;align-items:center;gap:6px;padding:0}
.menu-btn .caret{width:0;height:0;border:5px solid transparent;border-top-color:currentColor;margin-top:4px}
.menu-panel{
  /* 700 not 640: the longest label, "Single glazing & leaded lights", needs
     199px and a 640px panel only gives each column 185px, so it wrapped and
     left "lights" orphaned on its own line while every other item sat on one. */
  position:absolute;top:calc(100% + 16px);left:-20px;min-width:700px;padding:22px;
  display:grid;grid-template-columns:repeat(3,1fr);gap:20px;border-radius:18px;
  background:rgba(14,33,38,.9);backdrop-filter:blur(24px) saturate(150%);
  -webkit-backdrop-filter:blur(24px) saturate(150%);
  border:1px solid var(--edge);box-shadow:0 30px 70px -30px rgba(0,0,0,.95);
}
.menu-panel[hidden]{display:none}
.mcol h4{font-size:11.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--sky);margin-bottom:9px}
.mcol h4 span{display:block;font-size:11px;font-weight:400;letter-spacing:0;
  text-transform:none;color:var(--faint);margin-top:3px}
.mcol a{display:block;font-size:14.5px;color:#D3E5E6;padding:5px 0}
.mcol a:hover{color:#fff}
.menu-all{grid-column:1/-1;border-top:1px solid var(--edge-soft);padding-top:14px;
  font-weight:600;font-size:14px;color:var(--bright)}

/* ── hero ──────────────────────────────────────────────────────────────── */
.hero{position:relative;overflow:visible;background:none}
.hero::after{display:none}
.hero-bg{display:none}
.hero .wrap{position:relative;z-index:2;display:grid;gap:38px;padding:70px 22px 40px}
@media(min-width:960px){.hero .wrap{grid-template-columns:1.08fr .92fr;align-items:start;padding:84px 22px 46px}}
/* The quote form is a section on its own now, under the photo band, so it must
   not inherit the old two-column split — it would sit in a half-width column
   with nothing beside it. */
.hero.quote-section .wrap{display:block;padding-top:34px}
@media(min-width:960px){
  .hero.quote-section .wrap{grid-template-columns:none;padding:38px 22px 46px}
  .hero.quote-section .quote-card{max-width:760px;margin:0 auto}
}

/* ── folded quote form ─────────────────────────────────────────────────────
   <summary> is styled as the button. It needs its native marker removing in
   two ways: list-style for Firefox and the -webkit pseudo-element for Safari.
   Both, not either.                                                        */
/* Every <details> on the site is styled as an FAQ row — glass panel, padding,
   and a +/− marker on the summary. This one is a form disclosure, not an FAQ
   answer, so it opts out of all of that: without these three lines the toggle
   renders inside a second panel with a stray "+" underneath it. Opting out
   here rather than scoping the FAQ rules to .faq, because the area pages put
   their <details> outside that wrapper and would lose their styling. */
.quote-fold{max-width:760px;margin:0 auto;padding:0;background:none;border:0;
  border-radius:0;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none}
.quote-toggle::after{content:none}
.quote-toggle{
  cursor:pointer;list-style:none;display:flex;flex-direction:column;gap:4px;
  align-items:center;text-align:center;padding:18px 26px;border-radius:16px;
  background:linear-gradient(150deg,rgba(143,211,218,.22),rgba(255,255,255,.05));
  border:1px solid rgba(143,211,218,.34);
  transition:background .15s,border-color .15s}
.quote-toggle::-webkit-details-marker{display:none}
.quote-toggle:hover{background:linear-gradient(150deg,rgba(143,211,218,.3),rgba(255,255,255,.08));
  border-color:rgba(143,211,218,.5)}
.quote-toggle:focus-visible{outline:2px solid var(--bright);outline-offset:3px}
.qt-main{font-size:19px;font-weight:700;color:#fff;display:flex;align-items:center;gap:10px}
/* Chevron flips when the panel is open, so the control says which way it goes. */
.qt-main::after{content:"";width:9px;height:9px;border-right:2px solid var(--bright);
  border-bottom:2px solid var(--bright);transform:rotate(45deg);margin-top:-4px;
  transition:transform .18s}
.quote-fold[open] .qt-main::after{transform:rotate(-135deg);margin-top:2px}
.qt-sub{font-size:14px;color:#AFC8CA}
.quote-fold[open] .quote-toggle{margin-bottom:16px}
@media(prefers-reduced-motion:reduce){.qt-main::after{transition:none}}

/* ── hero band (photo + type) ──────────────────────────────────────────────
   Two layouts from one piece of markup.
   Wide: .hb-media is an absolute backdrop and every bit of type sits on top of
   it down the left, over a horizontal scrim.
   Narrow: .hb-media becomes an ordinary 350px block with only .hb-head over
   its foot, and the rest of the copy flows underneath on the page ground.
   That split is not cosmetic — a 16:9 photo inside a tall narrow band only
   ever shows about a third of its width, which on a phone was her hair and one
   shoulder, with the mug and her face both cropped clean out.               */
/* padding:0 overrides the generic section padding. On wide screens it made the
   band needlessly tall; on phones, where .hb-media is a normal block rather
   than an absolute backdrop, it showed as a 56px dark gap between the header
   and the top of the photo. .wrap sets the real spacing. */
/* No overflow:hidden here, deliberately. It made the band a scroll container,
   which did two bad things at once: it clipped the trust row (whose last line
   sits a few px past the band's edge, so the text was sliced through
   horizontally), and it became the nearest scrollport for
   `animation-timeline: view()`, so the site's reveal animations measured
   themselves against the band instead of the viewport and stuck part-way —
   leaving that copy sitting at ~26% opacity, which read as covered-up text.
   The image needs no clipping from here: object-fit:cover already clips to
   .hb-media's own box. */
.hero-band{position:relative;isolation:isolate;padding:0}
.hb-media{position:absolute;inset:0;z-index:0;overflow:hidden}
.hb-media img{width:100%;height:100%;object-fit:cover;object-position:62% 30%}
/* Heavy on the left where the type sits, nearly clear on the right so she is
   not buried. Horizontal ramp for legibility, plus a bottom fade so the band
   joins the dark page instead of stopping dead against it. */
.hb-media::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(90deg, rgba(9,17,20,.94) 0%, rgba(9,17,20,.88) 34%,
                           rgba(9,17,20,.55) 58%, rgba(9,17,20,.20) 78%,
                           rgba(9,17,20,.34) 100%),
    linear-gradient(180deg, rgba(9,17,20,.55) 0%, rgba(9,17,20,0) 26%,
                            rgba(9,17,20,0) 62%, rgba(9,17,20,.92) 100%)}
.hero-band .wrap{position:relative;z-index:2;padding:74px 22px 78px;
  min-height:clamp(430px,56vh,560px);display:flex;flex-direction:column;
  justify-content:center;align-items:flex-start}
.hero-band h1{
  font-size:clamp(36px,5.4vw,60px);max-width:15ch;margin:20px 0 0;line-height:1.04;
  background:linear-gradient(168deg,#FFFFFF 16%,#A8D7DC 80%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.hero-band .lede{font-size:clamp(16px,1.7vw,19px);color:#C9DFE1;max-width:46ch;
  margin-top:18px;line-height:1.55}
.hero-band .cta-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:26px}
.hero-band .trust{display:flex;flex-wrap:wrap;gap:18px;margin-top:26px;
  font-size:14px;color:#B7CFD1}
.hero-band .trust div{display:flex;align-items:center;gap:8px}
/* Wide screens: the head is simply the first two items of the left-hand stack. */
@media(min-width:761px){ .hb-head{display:contents} }
@media(max-width:760px){
  /* Band height is the zoom control: cover scales to the taller side, so a
     TALLER band gives a MORE cropped picture. 540 filled the frame with her
     and lost the window entirely; 350 pulls back to show the glazing bars and
     the reveal, which is the whole point of the shot on a glazier's site.
     96% across pans the view to the far right of the frame, putting her on the
     left and handing the right half to the glazed door, its handle and the
     daylight beyond. Panning this way is also the safe direction — the mug is
     on her right, so it only comes further into shot. Going the other way
     loses it: at 14% only a sliver was left. Checked at 360/390/430 wide. */
  .hb-media{position:relative;inset:auto;height:350px}
  .hb-media img{object-position:96% 36%}
  .hb-media::after{background:
    linear-gradient(180deg, rgba(9,17,20,.10) 0%, rgba(9,17,20,0) 34%,
                            rgba(9,17,20,.66) 74%, rgba(9,17,20,.96) 100%)}
  /* The whole .wrap is pulled up so the head overlaps the foot of the photo.
     .hb-head carries its own gradient rather than relying on the pull being
     exact, because the head's height changes with how the headline wraps. */
  .hero-band .wrap{min-height:0;padding:0 20px 8px;margin-top:-80px}
  .hb-head{margin:0 -20px;padding:30px 20px 10px;
    background:linear-gradient(180deg, rgba(9,17,20,0) 0%, rgba(9,17,20,.62) 34%,
                                       rgba(9,17,20,.90) 68%, rgba(9,17,20,1) 100%)}
  .hero-band h1{font-size:clamp(30px,8.4vw,40px);max-width:none;margin-top:16px}
  .hero-band .lede{margin-top:14px}
  .hero-band .trust{gap:10px 18px}
}
.eyebrow{
  display:inline-flex;align-items:center;gap:9px;font-size:12px;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:#A9CBCE;
  border:1px solid rgba(255,255,255,.16);padding:7px 14px;border-radius:999px;background:none;
}
.eyebrow::before{content:"";width:7px;height:7px;background:var(--bright);transform:rotate(45deg)}
.hero h1{
  font-size:clamp(38px,6.2vw,68px);max-width:13ch;margin:22px 0 0;
  background:linear-gradient(168deg,#FFFFFF 16%,#A8D7DC 80%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.hero p.lede{font-size:clamp(17px,2vw,20px);color:#C3D9DA;max-width:44ch;margin-top:22px;line-height:1.55}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:14px 24px;border-radius:12px;font-weight:700;font-size:16.5px;border:0;cursor:pointer;
  font-family:inherit;transition:transform .14s ease}
.btn:hover{transform:translateY(-1px)}
.btn:not(.ghost),.btn-primary,.btn-call{color:#062024;background:linear-gradient(160deg,var(--bright),var(--sky));
  box-shadow:0 12px 30px -12px rgba(143,211,218,.8)}
.btn-ghost,.btn.ghost{background:none;border:1px solid rgba(255,255,255,.22);color:var(--text);box-shadow:none}
.hero .trust{display:flex;flex-wrap:wrap;gap:14px 26px;margin-top:28px}
.hero .trust div{display:flex;align-items:center;gap:9px;font-weight:500;font-size:14.5px;color:#B9D2D4}

/* ── quote card ────────────────────────────────────────────────────────── */
.quote-card{padding:26px}
.quote-card h2{font-size:19px;font-weight:700}
.quote-card .sub{font-size:13.5px;color:var(--faint);margin:4px 0 18px}
.field{margin-bottom:11px}
.field label{display:block;font-size:11.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--faint);margin-bottom:5px}
.field input,.field select,.field textarea{
  width:100%;padding:11px 13px;border-radius:10px;font-size:15px;font-family:inherit;
  color:var(--text);background:rgba(255,255,255,.06);border:1px solid var(--edge);outline:none;
  transition:border-color .15s}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--bright)}
.field textarea{resize:vertical;min-height:74px}
.field select option{background:#0E2126;color:var(--text)}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:11px}
.opt,.photo-why,.form-note,.estimate-note,.photo-hint{color:var(--faint)}
.photo-pick{display:inline-flex;align-items:center;gap:9px;cursor:pointer;padding:11px 16px;
  border:1.5px dashed var(--edge);border-radius:10px;background:rgba(255,255,255,.04);
  color:#CFE4E5;font-weight:600;font-size:15px}
.photo-pick:hover{border-color:var(--bright)}
.photo-thumb{border:1px solid var(--edge);background:rgba(255,255,255,.05);border-radius:9px}
.photo-thumb figcaption{color:var(--faint)}

/* ── proof band ────────────────────────────────────────────────────────── */
.proof-band{background:rgba(255,255,255,.03);border-block:1px solid var(--edge-soft);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.proof-band .wrap{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  padding-block:22px}
.proof-item{text-align:left}
.proof-item b{display:block;font-size:19px;font-weight:700;color:#fff;letter-spacing:-.02em}
.proof-item span{font-size:12.5px;color:var(--faint)}

/* ── section rhythm: all sections are transparent, the ground shows ───── */
section{background:none !important;position:relative}
section > .wrap{padding-block:62px}
.section-head{max-width:52ch;margin-bottom:30px}
.kicker{font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--sky)}
.section-head h2{font-size:clamp(27px,4vw,40px);margin:12px 0 10px;color:#fff}
.section-head p{font-size:16.5px;color:var(--muted)}

/* ── service cards ─────────────────────────────────────────────────────── */
.services,.svc-grid,.why-grid,.reviews,.rel-grid,.work-grid{
  display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(258px,1fr))}
.service,.svc-card{padding:24px}
.service:first-child{background:linear-gradient(150deg,rgba(143,211,218,.16),rgba(255,255,255,.03))}
.service .ic{width:34px;height:34px;display:grid;place-items:center;border-radius:9px;margin-bottom:13px;
  background:linear-gradient(160deg,rgba(143,211,218,.3),rgba(95,168,176,.14));
  border:1px solid rgba(143,211,218,.28);color:var(--bright)}
.service h3,.svc-card h3{font-size:17.5px;font-weight:700;margin-bottom:7px}
.service p,.svc-card p{font-size:14.5px;color:#AFC8CA}
.btn-link{color:var(--bright);font-weight:600}

/* ── why / credentials ─────────────────────────────────────────────────── */
.why-item{padding:22px}
.why-item .n{font-size:24px;font-weight:800;color:var(--bright);letter-spacing:-.02em;margin-bottom:8px}
.why-item h4{font-size:16px;margin-bottom:5px}
.why-item p{font-size:14px;color:#AFC8CA}

/* ── areas ─────────────────────────────────────────────────────────────── */
.area-band{padding:30px}
.area-list{display:flex;flex-wrap:wrap;gap:9px;margin-top:18px}
.area-list span,.area-list a,.chip{
  display:inline-block;padding:7px 14px;border-radius:999px;font-size:14px;font-weight:500;
  background:rgba(255,255,255,.06);border:1px solid var(--edge-soft);color:#CFE4E5}
.area-list a:hover{background:rgba(143,211,218,.18);border-color:rgba(143,211,218,.4);color:#fff}
.area-chips{padding:20px 22px;border-radius:16px;background:rgba(255,255,255,.045);
  border:1px solid var(--edge-soft);margin:22px 0 28px}
.chips-head{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--sky);margin-bottom:12px}

/* ── reviews ───────────────────────────────────────────────────────────── */
/* Was justify-content:center, from when this was a three-column grid.
   Centring flex items inside an overflow-x container offsets the whole
   row and breaks scroll alignment — cards sat 252px off the left edge
   even at scrollLeft 0, which is what made the strip look full of gaps. */
.reviews{justify-content:flex-start}
.review{padding:24px}
.stars{color:var(--bright);letter-spacing:3px;font-size:15px;margin-bottom:11px}
.review p{font-size:15px;color:#CBE0E1}
.who{margin-top:14px;font-size:13px;color:var(--faint);font-weight:600}

/* ── FAQ ───────────────────────────────────────────────────────────────── */
.faq{max-width:780px;margin:0 auto}
details{padding:2px 20px;margin-bottom:12px;border-radius:14px}
details summary{cursor:pointer;font-weight:600;font-size:16.5px;color:#fff;padding:16px 0;
  list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px}
details summary::-webkit-details-marker{display:none}
details summary::after{content:"+";color:var(--bright);font-size:24px;font-weight:400;line-height:1}
details[open] summary::after{content:"−"}
details p{padding:0 0 18px;color:var(--muted);font-size:15px}

/* ── inner pages ───────────────────────────────────────────────────────── */
main.svc > .wrap{padding-block:0 70px}
.crumbs{font-size:13px;color:var(--faint);padding:22px 0 0}
.crumbs a{color:#C4DEE0}
.crumbs span{opacity:.5;margin:0 4px}
.svc-body{padding:34px clamp(22px,4vw,44px) 40px;margin-top:20px;border-radius:22px}
.svc-body h1{font-size:clamp(31px,4.6vw,50px);
  background:linear-gradient(168deg,#FFFFFF 18%,#A8D7DC 82%);
  -webkit-background-clip:text;background-clip:text;color:transparent;max-width:16ch}
.svc-body .lede{font-size:clamp(17px,1.9vw,20px);color:#C3D9DA;margin-top:18px;max-width:52ch;line-height:1.55}
.svc-body h2{font-size:clamp(21px,2.7vw,29px);margin:34px 0 11px;max-width:24ch}
.svc-body p{font-size:16.5px;line-height:1.72;max-width:64ch}
.svc-shot img,.svc-diagram svg{border-radius:16px;border:1px solid var(--edge)}
.svc-shot img{max-height:400px;object-fit:cover;width:100%}
.svc-shot{margin:26px 0 30px}
.svc-shot figcaption,.svc-diagram figcaption{
  margin-top:12px;font-size:14px;color:var(--faint);padding-left:14px;
  border-left:3px solid rgba(143,211,218,.35);max-width:62ch}
.svc-diagram svg{background:rgba(255,255,255,.9);padding:14px}

/* service-page hero — sits on the page ground, not inside a pane */
.svc-hero .wrap{padding-block:0 6px}
.svc-hero .crumbs{padding-top:24px}
.svc-hero h1{font-size:clamp(34px,5.4vw,62px);line-height:1;letter-spacing:-.038em;
  margin-top:16px;max-width:15ch;
  background:linear-gradient(168deg,#FFFFFF 16%,#A8D7DC 80%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.svc-hero .lede{font-size:clamp(17px,2vw,20.5px);color:#C3D9DA;max-width:52ch;
  margin-top:20px;line-height:1.56}
.svc-hero .hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
.svc-hero .facts{display:grid;gap:12px;margin-top:34px;
  grid-template-columns:repeat(auto-fit,minmax(168px,1fr))}
.svc-hero .facts .pane{padding:15px 18px}
.svc-hero .facts b{display:block;font-size:21px;font-weight:800;letter-spacing:-.02em;color:#fff}
.svc-hero .facts span{font-size:13px;color:var(--muted)}

/* on service pages the article is just a stack — the panes inside carry the glass */
.svc-body.plain{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;
  border:0;box-shadow:none;padding:0;margin-top:34px;
  display:flex;flex-direction:column;gap:20px}
.svc-body.plain > .pane.block{padding:26px clamp(20px,3vw,34px)}
.svc-body.plain > .pane.block h2{margin:0 0 10px}
.svc-body.plain > .svc-shot,.svc-body.plain > .svc-diagram{margin:0}
.svc-body.plain > .svc-cta{margin:0}
.svc-body.plain > .svc-faq,.svc-body.plain > .svc-related{
  margin:0;padding:26px clamp(20px,3vw,34px);border-radius:18px;
  background:var(--pane);border:1px solid var(--edge);
  backdrop-filter:blur(20px) saturate(140%);-webkit-backdrop-filter:blur(20px) saturate(140%)}
.svc-body.plain > .svc-faq > h2,.svc-body.plain > .svc-related > h2{margin:0 0 14px}

.svc-cta{margin:38px 0 8px;padding:26px;border-radius:16px;
  background:linear-gradient(150deg,rgba(143,211,218,.16),rgba(255,255,255,.03));
  border:1px solid rgba(143,211,218,.24)}
.svc-cta h2{margin:0 0 8px;font-size:22px}
.svc-cta p{font-size:15.5px}
.svc-cta .trust{margin-top:14px;font-size:13px;color:var(--faint)}
.svc-faq{margin-top:38px}
.svc-related{margin-top:38px}
.related,.rel-grid{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px}
.rel{padding:11px 16px;border-radius:11px;font-size:14.5px;font-weight:500;color:#CFE4E5;
  border-radius:11px}
.rel:hover{color:#fff;border-color:rgba(143,211,218,.45)}

/* ── footer ────────────────────────────────────────────────────────────── */
footer.site{margin-top:40px;background:rgba(6,14,15,.6);border-top:1px solid var(--edge-soft);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
footer.site .wrap{padding-block:48px 30px}
.foot-blurb,.foot-bottom{color:var(--faint)}
footer.site h4{font-size:11.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--sky);margin-bottom:12px}
footer.site a{color:#C7DEE0}
footer.site a:hover{color:#fff}
.foot-bottom{border-top:1px solid var(--edge-soft);margin-top:30px;padding-top:20px;
  text-align:center;font-size:13.5px}
.foot-bottom .built{display:block;margin-top:7px;font-size:12px;color:rgba(255,255,255,.34)}

/* ── mobile call bar ───────────────────────────────────────────────────── */
.mobile-bar{position:fixed;left:0;right:0;bottom:0;z-index:60;display:flex;
  background:rgba(11,21,22,.82);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-top:1px solid var(--edge)}
.mobile-bar a{flex:1;text-align:center;padding:14px;font-weight:700;font-size:15.5px}
.mobile-bar .call{color:#fff}
.mobile-bar .quote{color:#062024;background:linear-gradient(160deg,var(--bright),var(--sky))}
@media(min-width:880px){.mobile-bar{display:none}}
@media(max-width:879px){body{padding-bottom:58px}}

/* ── mobile nav ────────────────────────────────────────────────────────── */
.burger{background:none;border:1px solid var(--edge);border-radius:9px;padding:8px 10px;
  color:#fff;cursor:pointer}
@media(min-width:940px){.burger{display:none}}
#mnav{background:rgba(11,21,22,.95);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border-bottom:1px solid var(--edge)}
#mnav a{display:block;padding:12px 22px;color:#D3E5E6;border-bottom:1px solid var(--edge-soft)}

/* ── before/after slider keeps working, just re-skinned ────────────────── */
.ba-stage{border-radius:18px;border:1px solid var(--edge)}
.ba-tag{background:rgba(6,14,15,.75);color:#fff}
.ba-grip{background:#fff;color:var(--deep)}
.work-lead h3{font-size:22px;margin-bottom:10px}
.work-lead p{color:#B4CCCE}
.ba-cap{color:var(--faint);font-size:14px}
.shot{overflow:hidden}
.shot img{border-radius:0}
.shot figcaption{padding:14px 16px 16px;font-size:14px;color:#AFC8CA}
.shot figcaption b{display:block;color:#fff;font-weight:600;margin-bottom:3px}

/* ── scroll-driven reveals (below the fold only) ───────────────────────── */
@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    section > .wrap > *, .svc-body, .area-chips, .svc-cta, .svc-faq, .svc-related{
      animation:gs-rise linear both;
      animation-timeline:view();
      /* A LENGTH, not a percentage of the element. `cover 26%` is 26% of the
         way through covering *this element*, so the taller the element the
         longer it stays faded: .svc-body is the whole article, 3,800px on an
         area page, which left the page people were reading sitting at 0.68
         opacity for a thousand pixels of scroll. Everything looked washed
         out and nothing on the page said why. A fixed distance reveals every
         block over the same 340px, whatever its height. */
      animation-range:entry 4% entry 340px;
    }
    /* never the hero, the header, or anything else on screen at load */
    .hero .wrap > *, header.site *, .proof-band *{animation:none}
    @keyframes gs-rise{
      from{opacity:0;transform:translateY(22px) scale(.988)}
      to{opacity:1;transform:none}
    }
  }
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *{animation:none !important;transition:none !important}
}

/* ── base-layer repair ──────────────────────────────────────────────────────
   site.css loads underneath this file for its layout (grids, the before/after
   slider, the contact and credentials cards). It was written for a light page,
   so it uses --ink and --deep as *dark text* colours. This file redefines those
   same tokens as the dark *ground*, which turns every one of those rules into
   dark-on-dark. These are the rules that survived the theme with no override.
   Anything added to site.css that paints text must be re-checked here.        */
.review .who{color:#fff}
.cred .badge{color:#062024;background:linear-gradient(160deg,var(--bright),var(--sky))}
.cred h4{color:#fff}
.cred p{color:var(--muted)}
.cred .ref{color:var(--faint)}
.svc-cta .btn.ghost{color:var(--text)}
.menu-btn,.menu-btn:hover,nav.links > a{color:var(--text)}
.menu-btn:hover,nav.links > a:hover{color:#fff}
.svc-related h2{color:#fff}
.contact-card .big,.contact-card .big a{color:#fff}
.photo-field .opt{color:var(--muted)}
.ba-cap b{color:#fff}
.area-chips .chips-head{color:var(--sky)}

/* Light sections from the base layer. .svc and .why painted the old page bands;
   on the dark ground the sections must let the bloom through instead. */
main.svc,.svc,.why,.creds{background:none}
.mnav{background:rgba(14,33,38,.94);border-color:var(--edge);
  backdrop-filter:blur(24px) saturate(150%);-webkit-backdrop-filter:blur(24px) saturate(150%)}
.mnav a,.mnav h4,.mnav strong{color:var(--text)}
.mnav h4{color:var(--sky)}

/* Base-layer headings inside the article. site.css sets these to --deep, which
   is now a background colour, so they must be restated. h1 is left alone — it
   carries the gradient fill and needs color:transparent. */
.svc-body h2,.svc-body h3,.svc-body h4,
.pane.block h2,.svc-cta h2,.svc-faq h2,.svc-related h2{color:#fff}
.svc-body p,.svc-body li,.svc-body .lede{color:var(--muted)}

/* Remaining base-layer text on the homepage and contact page. */
.quote-card h2,.service h3,.work-lead h3,.cta-strip h2,
.contact-card h3,.why-item h3{color:#fff}
.quote-card .sub,.service p,.work-lead p,.cta-strip p,.contact-card p{color:var(--muted)}
.quote-card a:not(.btn),.contact-card a:not(.btn),.cta-strip a:not(.btn){color:var(--bright)}

/* These two cards keep their own light backgrounds from the base layer, so
   theming their text alone left white-on-pale. Make them panes like the rest. */
.cred,.contact-card{
  background:var(--pane);border:1px solid var(--edge);border-radius:18px;
  backdrop-filter:blur(20px) saturate(140%);-webkit-backdrop-filter:blur(20px) saturate(140%);
  box-shadow:0 1px 0 rgba(255,255,255,.2) inset, 0 22px 56px -30px rgba(0,0,0,.9)}
.contact-card h3{color:var(--sky)}
.form-note,.form-note a{color:var(--faint)}
.form-note a{color:var(--bright)}
.phone-inline{color:var(--bright);font-weight:700}
.privacy-sig{margin-top:40px;font-size:14px;color:var(--faint)}
/* The base layer set this as a small uppercase eyebrow; here it is a section
   heading like "Common questions" beside it, so match that instead. */
.svc-related h2{text-transform:none;letter-spacing:-.025em;
  font-size:clamp(21px,2.7vw,29px);color:#fff}
/* The base layer pads every <section> by 96px; the hero sets its own rhythm. */
.svc-hero{padding:0 0 4px}
.svc-hero + main.svc{padding-top:10px}
.svc-hero + main.svc .svc-body{margin-top:0}

/* ── quote form ─────────────────────────────────────────────────────────────
   site.css sizes the hero's intro paragraph with `.hero > .wrap p`, and the
   quote card sits inside .hero > .wrap, so every <p> of small print in the
   form was inheriting the 19px lede size. Restate each at its own size with
   enough specificity to beat that selector. */
.hero .quote-card p{font-size:13px;line-height:1.5}
.hero .quote-card .photo-why{font-size:13px;margin:2px 0 10px}
.hero .quote-card .photo-hint,
.hero .quote-card .estimate-note{font-size:12.5px}
.hero .quote-card .form-note{font-size:12px;margin-top:10px;text-align:center}
.hero .quote-card .sub{font-size:14.5px}
/* the card's own colour is still the base layer's dark-on-white value, so any
   text in it that nothing else styles would come out near-invisible */
.quote-card{color:var(--text)}

/* .btn-ghost is a separate class from .ghost, so the primary fill was landing
   on the hero's phone button and giving two identical buttons side by side. */
.btn.btn-ghost{background:none;border:1px solid rgba(255,255,255,.22);
  color:var(--text);box-shadow:none}
/* site.css puts a highlight border on `.hero form` as well as the card, which
   on the glass card draws a second rectangle inside the first. The card is the
   pane; the form is just its contents. */
.hero form{border:0;box-shadow:none}

/* ── "what do you need" suggestions ─────────────────────────────────────────
   These replaced a <select>. They fill the free-text box rather than acting as
   a menu, so nobody has to squeeze their job into a list we wrote. */
.suggest{display:flex;flex-wrap:wrap;gap:7px;margin-top:9px}
.suggest button{
  font:inherit;font-size:12.5px;font-weight:500;cursor:pointer;
  padding:6px 12px;border-radius:999px;color:#CFE4E5;
  background:rgba(255,255,255,.05);border:1px solid var(--edge-soft);
  transition:background .15s,border-color .15s,color .15s}
.suggest button:hover{background:rgba(143,211,218,.16);
  border-color:rgba(143,211,218,.45);color:#fff}

/* ── photo picker ───────────────────────────────────────────────────────────
   This is the thing that earns a same-day price, so it has to look like a
   control. As a faint dashed outline on the dark card it read as decoration. */
.hero .quote-card .photo-pick{
  display:flex;align-items:center;gap:14px;width:100%;
  /* .field label is an uppercase micro-label; this label is a control */
  text-transform:none;letter-spacing:normal;
  padding:16px 18px;border-radius:14px;cursor:pointer;
  color:var(--text);
  background:linear-gradient(150deg,rgba(143,211,218,.16),rgba(143,211,218,.05));
  border:1.5px dashed rgba(143,211,218,.5);
  transition:background .15s,border-color .15s}
.hero .quote-card .photo-pick:hover{
  background:linear-gradient(150deg,rgba(143,211,218,.26),rgba(143,211,218,.09));
  border-color:rgba(143,211,218,.8)}
.hero .quote-card .photo-pick svg{color:var(--bright);flex-shrink:0}
.photo-pick .pick-text{display:flex;flex-direction:column;gap:2px;text-align:left}
.photo-pick .pick-text b{font-size:15px;font-weight:700;color:#fff;letter-spacing:-.01em}
.photo-pick .pick-text small{font-size:12px;color:var(--muted);line-height:1.35}

/* ── the provisional-quote offer ────────────────────────────────────────────
   Was grey small print under the button, where it read as a disclaimer. It is
   the offer, so it gets its own block next to the photo picker. */
.how-price{margin-top:18px;padding:16px 18px;border-radius:14px;
  background:linear-gradient(150deg,rgba(143,211,218,.13),rgba(255,255,255,.02));
  border:1px solid rgba(143,211,218,.22)}
.how-price h3{font-size:15px;font-weight:700;color:#fff;margin-bottom:7px;letter-spacing:-.01em}
.hero .quote-card .how-price p{font-size:12.8px;line-height:1.55;color:var(--muted)}
.hero .quote-card .how-price p + p{margin-top:8px}
.how-price b{color:#fff;font-weight:700}

/* ── reviews rail ───────────────────────────────────────────────────────────
   The base layer lays reviews out as a 3-column grid, which stops working the
   moment there are more than three. This overrides it to a scroll-snap rail:
   swipeable on a phone with no JS, and the arrows/dots are enhancement only.
   If the script never runs you can still scroll the strip by hand.            */
.rv{position:relative}
.reviews{
  display:flex;gap:18px;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-padding:0 2px;
  padding:4px 2px 14px;margin:0;
  grid-template-columns:none;                 /* kill the base-layer grid */
  scrollbar-width:none;-ms-overflow-style:none}
.reviews::-webkit-scrollbar{display:none}
/* One card at a time on a phone, with a sliver of the next showing so it is
   obvious the strip moves. A fixed 360px card in a ~560px rail left one and a
   half cards visible and the second one clipped mid-sentence, which read as a
   broken layout rather than a carousel. */
.reviews > .review{
  flex:0 0 calc(100% - 34px);scroll-snap-align:start;scroll-snap-stop:always;
  padding:24px;border-radius:18px;display:flex;flex-direction:column}
@media(min-width:780px){ .reviews > .review{flex-basis:calc((100% - 18px)/2)} }
@media(min-width:1080px){ .reviews > .review{flex-basis:calc((100% - 36px)/3)} }
.reviews .stars{color:#F0C674;letter-spacing:2px;font-size:15px;margin-bottom:10px}
.reviews .review p{font-size:15.5px;line-height:1.62;color:var(--text);flex:1}
.reviews .review .who{margin-top:16px;font-weight:600;font-size:13.5px;color:var(--sky)}
.reviews:focus-visible{outline:2px solid var(--bright);outline-offset:4px;border-radius:18px}

.rv-controls{display:flex;align-items:center;justify-content:center;gap:14px;margin-top:6px}
.rv-arrow{
  display:grid;place-items:center;width:38px;height:38px;border-radius:50%;cursor:pointer;
  color:var(--text);background:rgba(255,255,255,.06);border:1px solid var(--edge);
  transition:background .15s,border-color .15s,opacity .15s}
.rv-arrow:hover{background:rgba(143,211,218,.18);border-color:rgba(143,211,218,.5)}
.rv-arrow[disabled]{opacity:.3;cursor:default}
.rv-arrow[disabled]:hover{background:rgba(255,255,255,.06);border-color:var(--edge)}
.rv-dots{display:flex;gap:7px}
.rv-dot{
  width:8px;height:8px;padding:0;border-radius:50%;cursor:pointer;
  background:rgba(255,255,255,.22);border:0;transition:background .15s,width .15s}
.rv-dot[aria-current="true"]{background:var(--bright);width:20px;border-radius:5px}
@media(prefers-reduced-motion:reduce){.reviews{scroll-behavior:auto}}

/* ── no backdrop-filter ─────────────────────────────────────────────────────
   The whole look leans on backdrop-filter, which is only reliable from about
   2022 (Firefox 103, Samsung Internet 12). On an older Android the panes are
   near-invisible — they are mostly-transparent white over a dark ground, and
   it is the blur that gives them any body — and the sticky header turns into a
   58%-opaque strip with the page scrolling through it behind the nav links.
   Give those browsers solid surfaces instead. It loses the frosted effect and
   keeps the site usable, which is the right way round.                        */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pane,.quote-card,.service,.why-item,.review,.svc-card,.shot,.rel,
  .creds-item,.area-band,.svc-body,details,.cred,.contact-card,
  .svc-body.plain > .svc-faq,.svc-body.plain > .svc-related{
    background:rgba(24,50,56,.94)}
  header.site{background:#0d1e21}
  .menu-panel{background:#102a30}
  .mobile-bar{background:#0d1e21}
  footer.site{background:#0a1719}
  .svc-hero .facts .pane{background:rgba(24,50,56,.94)}
}

/* ── touch targets ──────────────────────────────────────────────────────────
   Measured at 390px: the suggestion chips came out 35px tall, the review
   arrows 38px and the burger 38px. All three are things a thumb has to hit,
   and the burger is how the whole site is navigated on a phone. 44px is the
   usual floor. Kept the visual size by growing the hit area rather than the
   look — min-height plus centred content, not fatter padding.                */
.suggest button{min-height:44px;display:inline-flex;align-items:center}
.rv-arrow{width:46px;height:46px}   /* 44 measured 43 after rounding */
/* The bars are three empty <span>s coloured with var(--deep) by the base
   layer. This file redefines --deep as the dark GROUND, so they have been
   dark-on-dark and invisible since the theme went on — the menu button has
   been rendering as an empty outlined box on every phone. They also need
   align-items:stretch: the spans have a height but no width, so centring
   them collapses them to nothing. */
.burger{min-width:44px;min-height:44px;display:inline-flex;
  flex-direction:column;align-items:stretch;justify-content:center;gap:4px;
  padding:12px 10px}
.burger span{background:#fff;height:2px;border-radius:2px;width:auto}

/* At 390px the brand name wrapped to two lines and the tagline to three, so
   the text block (73px) was taller than the header (69px) and spilled out of
   it. The tagline is decoration — drop it on narrow screens and keep the name
   on one line. */
@media(max-width:520px){
  .brand-text small{display:none}
  .brand-text{white-space:nowrap}
  .brand{font-size:16.5px;gap:9px}
  /* The header cannot hold the logo, the name, the burger AND a button at
     this width — the burger ended up sitting on top of the name. The button
     is the thing to drop: the fixed bar at the bottom of the screen already
     offers Call and Get a quote, so this was a third copy of the same action. */
  header.site .nav-cta{display:none}
  header.site .wrap{gap:10px}
}

/* ── accreditation logo ─────────────────────────────────────────────────────
   The Certass mark is navy and orange, drawn for white paper. On the dark card
   the navy all but disappears, so it sits on a small light plaque rather than
   directly on the glass. Third-party marks should not be recoloured to suit a
   theme — the plaque respects the logo and keeps it legible.                 */
.cred-proof{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:16px}
.cred-logo{
  background:#fff;border-radius:8px;padding:7px 10px;
  width:110px;height:auto;display:block;
  box-shadow:0 1px 0 rgba(255,255,255,.25) inset, 0 6px 18px -10px rgba(0,0,0,.8)}
.cred-proof .ref{margin:0}

/* ── in-page anchors ────────────────────────────────────────────────────────
   Every section the nav points at needs to clear the sticky header, or the
   heading lands underneath it and the section looks like it starts mid-text.
   scroll-margin-top is the property the browser honours when jumping to an
   anchor, not padding or margin. */
section[id]{scroll-margin-top:88px}
/* #quote is a div, not a section, so the rule above never caught it. It did
   not matter while the form sat beside the headline at the top of the page and
   "Get a free quote" barely scrolled; now the form is a full band below the
   photo, that jump is ~1050px and landed its heading squarely under the
   header. */
[id]{scroll-margin-top:88px}

/* ── area pages: work strip, service list, how it works ─────────────────────
   These three blocks were added to site.css after the glass theme landed, so
   they arrived painted for a light page and nothing here restated them. The
   result on the dark ground: the service list was --ink text (now the ground)
   on the ground itself — legible only as a silhouette — hung off --line
   hairlines that are near-white, and the four steps were bright white cards
   carrying headings that .svc-body h3 had already turned white.

   This is the failure the base-layer repair note above warns about, so the
   same note applies twice over: anything added to site.css that paints a
   surface or text has to be restated here, or it ships inverted.            */

/* Mark's six real jobs. A pane, like every other card on the dark ground —
   not a white photo frame. */
.work-note{color:var(--faint);font-size:13.5px}
.work-strip figure{background:var(--pane);border:1px solid var(--edge-soft);
  border-radius:14px;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.work-strip figcaption{color:var(--muted)}

/* The grouped service list. Sixteen links, so the row itself carries almost no
   weight: a faint rule between each, a glass tile for the icon, and the accent
   saved for hover so the list reads as one block rather than sixteen buttons. */
.sgroup h3{color:#fff}
.sgroup .sg-sub{color:var(--faint)}
.sgroup li{border-top-color:var(--edge-soft)}
.sgroup li:last-child{border-bottom-color:var(--edge-soft)}
.sgroup a{color:var(--text)}
.sgroup .arw{color:var(--faint)}
.ic{background:rgba(255,255,255,.06);border:1px solid var(--edge-soft);color:var(--bright)}
.sgroup a:hover{color:var(--bright)}
.sgroup a:hover .arw{color:var(--bright)}
.sgroup a:hover .ic{background:rgba(143,211,218,.16);border-color:rgba(143,211,218,.38)}

/* The service you're already on: present, but plainly not a link. */
.sgroup li.here .cur{color:var(--muted)}
.sgroup li.here .ic{background:rgba(143,211,218,.14);color:var(--bright)}
.sgroup li.here .arw{color:var(--sky)}

/* How it works. */
.step{background:var(--pane);border:1px solid var(--edge-soft);border-radius:14px;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.step::before{background:linear-gradient(160deg,var(--bright),var(--sky));color:#062024}
.step h3{color:#fff}
.step p{color:var(--muted)}
