/* ============ Ashton Studios — dark tech, lusion-leaning ============ */

:root {
  --bg: #0b0a09;
  --bg-raise: #12100e;
  --bg-card: #161311;
  --ink: #efeae1;
  --ink-dim: #97918a;
  --accent: #d8bd8d;
  --accent-ink: #191308;
  --line: #29251f;

  --font: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --serif: "Fraunces", Georgia, serif;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;

  --text-base: clamp(1rem, 0.94rem + 0.3vw, 1.15rem);
  --text-display: clamp(2.6rem, 0.6rem + 9.2vw, 8.6rem);
  --text-display-md: clamp(2.2rem, 1rem + 5.4vw, 5.4rem);
  --text-title: clamp(1.9rem, 1rem + 3.6vw, 3.8rem);

  --space-section: clamp(5.5rem, 3rem + 10vw, 15rem);
  --gutter: clamp(1.1rem, 4vw, 4rem);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  /* Motion scale, raised 30 Aug on Ashton's note that the page felt too
     subtle. Travel and duration are deliberately large — this is a portfolio
     site whose job is to look like the person built it. Every value below is
     compositor-only (transform/opacity/clip-path) and every one is switched
     off wholesale by the reduced-motion block at the end of this file. */
  --dur: 1050ms;
  --travel: 72px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
::selection { background: var(--accent); color: var(--accent-ink); }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* film grain — fixed, subtle, no pointer cost */
.grain {
  position: fixed; inset: -50%; z-index: 90; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: .045; mix-blend-mode: overlay;
}
.skip { position: fixed; top: -4rem; left: 1rem; z-index: 99; background: var(--accent); color: var(--accent-ink); padding: .6rem 1rem; font-weight: 700; transition: top .2s; }
.skip:focus { top: 1rem; }

.accent { color: var(--accent); }
/* editorial serif italic for accent words inside display type — the luxury contrast */
.display .accent, .display-md .accent, .display-sm .accent, .section-title .accent {
  font-family: var(--serif); font-style: italic; font-weight: 380;
  text-transform: lowercase; letter-spacing: 0; font-size: 1.02em; line-height: 1.06;
}

/* ============ header ============ */
.site-head {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex; align-items: center; gap: 2rem;
  padding: .9rem var(--gutter);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.wordmark { text-decoration: none; font-weight: 900; letter-spacing: .04em; font-size: 1.02rem; }
.wordmark-s { color: var(--accent); margin-left: .35ch; }
.site-head nav { margin-left: auto; display: flex; gap: 1.6rem; }
.site-head nav a {
  text-decoration: none; color: var(--ink-dim); font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em;
  transition: color .2s;
}
.site-head nav a:hover { color: var(--accent); }
.site-head nav a {
  background: linear-gradient(var(--accent), var(--accent)) bottom left / 0% 1px no-repeat;
  padding-bottom: .3rem;
  transition: color .2s, background-size .45s var(--ease-out);
}
.site-head nav a:hover { background-size: 100% 1px; }

/* buttons */
.btn {
  display: inline-block; text-decoration: none; font-weight: 800; letter-spacing: .01em;
  padding: .8rem 1.5rem; border-radius: 999px; font-size: .98rem;
  transition: transform .25s var(--ease-out), background .2s, color .2s, border-color .2s;
  will-change: transform;
}
.btn-solid { background: var(--ink); color: #131008; }
.btn-solid:hover { background: #ffffff; }
.btn-ghost { border: 1px solid var(--line); color: var(--ink); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-big { padding: 1.1rem 2rem; font-size: clamp(1rem, .8rem + 1vw, 1.35rem); }
.head-cta { padding: .55rem 1.1rem; font-size: .88rem; }

/* ============ hero ============ */
.hero {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 7rem var(--gutter) 2rem;
  background: radial-gradient(58rem 34rem at 22% 18%, rgba(216, 189, 141, 0.05), transparent 66%);
}
#field { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-inner { position: relative; z-index: 2; max-width: 72rem; }

.eyebrow {
  font-family: var(--mono); font-size: .74rem; color: var(--ink-dim);
  text-transform: uppercase; letter-spacing: .22em; margin-bottom: 1.6rem;
  display: flex; align-items: center; gap: .8rem;
}
.tick { width: 1.6rem; height: 1px; background: var(--accent); display: inline-block; }

.display, .display-md, .display-sm, .section-title {
  font-weight: 900; font-stretch: 90%;
  line-height: .92; letter-spacing: -0.015em; text-wrap: balance;
}
.display { font-size: var(--text-display); }
.display-md { font-size: var(--text-display-md); }
.display-sm { font-size: clamp(2rem, 1rem + 3.4vw, 3.6rem); }
.section-title { font-size: var(--text-title); }

/* The reveal mask. padding-bottom must clear the DEEPEST glyph any line can
   contain, not the average one: the accent line is italic Fraunces set at
   1.02em with line-height 1, whose descenders (g, y, j) drop far below the
   Archivo baseline. At .14em the hero's "googled you." was being sliced
   through its descenders and colliding with the paragraph beneath it —
   caught in a 1440x900 render 1 Sept, before go-live. .34em clears it with
   margin to spare; the negative margin cancels the reserved space so the
   line rhythm is unchanged. */
.display .line { display: block; overflow: hidden; padding-bottom: .34em; margin-bottom: -.34em; }
/* The negative margin above cancels the reserved descender space so lines
   inside the headline keep their tight rhythm — but on the LAST line that
   pulls the next element up INTO the descenders, which is how "googled you."
   ended up sitting on top of the hero paragraph. The final line keeps its
   reserved space; only the interior lines claw it back. */
.display .line:last-child { margin-bottom: 0; }
/* the headline wipe: each line swings up from below its own mask, pivoting
   on its bottom-left corner so it reads as weight arriving, not a fade */
.display .line > span {
  display: inline-block; transform-origin: 0% 100%;
  transform: translateY(112%) rotate(6deg);
  transition: transform 1300ms var(--ease-out);
}
.motion-armed .revealed .line > span, .no-motion .display .line > span { transform: translateY(0) rotate(0deg); }
.display .line:nth-child(2) > span { transition-delay: 150ms; }
.display .line:nth-child(3) > span { transition-delay: 300ms; }

.hero-sub { max-width: 34rem; margin-top: 1.6rem; color: var(--ink-dim); font-size: clamp(1.02rem, .9rem + .5vw, 1.25rem); }
.hero-ctas { display: flex; gap: .9rem; margin-top: 2.2rem; flex-wrap: wrap; }

.hero-foot {
  position: relative; z-index: 2;
  display: flex; gap: 2.4rem; align-items: center; flex-wrap: wrap;
  margin-top: auto; padding-top: 3rem;
  font-family: var(--mono); font-size: .85rem; color: var(--ink-dim);
}
.hero-foot strong { color: var(--ink); font-weight: 700; }
.scroll-cue { margin-left: auto; display: flex; align-items: center; gap: .6rem; }
.cue-line { width: 3.4rem; height: 1px; background: var(--line); position: relative; overflow: hidden; display: inline-block; }
.cue-line::after { content: ""; position: absolute; inset: 0; background: var(--accent); transform: translateX(-100%); animation: cue 2.2s var(--ease-out) infinite; }
@keyframes cue { 60% { transform: translateX(100%); } 100% { transform: translateX(100%); } }

/* ============ ticker ============ */
.ticker { border-block: 1px solid var(--line); overflow: hidden; padding: .9rem 0; background: var(--bg-raise); }
.ticker-track { display: flex; gap: 2.6rem; width: max-content; animation: ticker 40s linear infinite; }
.ticker-track span { font-weight: 900; font-size: 1.05rem; text-transform: uppercase; letter-spacing: .14em; white-space: nowrap; }
.ticker-track i { color: var(--accent); font-style: normal; }
@keyframes ticker { to { transform: translateX(calc(-100% / 3)); } }

/* ============ work — pinned horizontal scrub ============ */
/* 18 Sep 2026: seven cards became three (two clients + the CTA), so the pinned
   travel shrank with it — 440svh of scroll for ~400px of pan felt like a slog. */
.work { height: 230svh; position: relative; }
.work-sticky {
  position: sticky; top: 0; height: 100svh; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; gap: clamp(1.2rem, 3vh, 3rem);
  padding: 5.5rem 0 2rem;
}
.work-head { padding: 0 var(--gutter); display: flex; align-items: end; justify-content: space-between; gap: 2rem; flex-wrap: wrap; }
.work-note { max-width: 26rem; color: var(--ink-dim); font-size: .95rem; }

.work-track {
  display: flex; gap: clamp(1rem, 2.5vw, 2.4rem);
  padding: 0 var(--gutter);
  will-change: transform;
}
.work-card { flex: 0 0 clamp(19rem, 44vw, 34rem); }
.shot {
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--bg-card);
  transition: border-color .3s, transform .5s var(--ease-out);
}
.work-card:hover .shot { border-color: var(--accent); transform: translateY(-16px) scale(1.02); }
.shot img { transition: transform 1.1s var(--ease-out); }
.work-card:hover .shot img { transform: scale(1.09); }
/* depth during the horizontal scrub — app.js writes --depth (0 at the centre
   of the viewport, 1 at the edges) per card, so cards lift into focus as they
   pass and settle back as they leave */
.work-card {
  --depth: 0;
  transform: scale(calc(1 - var(--depth) * .1)) translateY(calc(var(--depth) * 26px));
  opacity: calc(1 - var(--depth) * .45);
  will-change: transform, opacity;
}
.no-motion .work-card, html:not(.motion-armed) .work-card { transform: none; opacity: 1; }
.chrome {
  display: flex; align-items: center; gap: .42rem; padding: .55rem .8rem;
  border-bottom: 1px solid var(--line); background: var(--bg-raise);
}
.chrome i { width: .55rem; height: .55rem; border-radius: 50%; background: var(--line); }
.chrome span { margin-left: .5rem; font-family: var(--mono); font-size: .68rem; color: var(--ink-dim); }
.card-meta { padding: 1rem .2rem 0; }
.card-meta h3 { font-size: 1.2rem; font-weight: 800; margin-top: .45rem; }
.card-meta p:last-child { color: var(--ink-dim); font-size: .92rem; }
.badge {
  display: inline-block; font-family: var(--mono); font-size: .68rem; letter-spacing: .08em;
  padding: .22rem .6rem; border: 1px solid var(--line); border-radius: 999px; color: var(--ink-dim);
}
.badge-live { border-color: var(--accent); color: var(--accent); }

.work-card-cta { display: flex; align-items: center; }
.cta-card { padding: 1rem; display: grid; gap: 1.2rem; justify-items: start; }
.cta-card p { color: var(--ink-dim); max-width: 22rem; }

.work-progress { height: 2px; background: var(--line); margin: 0 var(--gutter); border-radius: 2px; overflow: hidden; }
.work-progress span { display: block; height: 100%; width: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left; }

/* narrow / reduced-motion fallback: native horizontal scroll */
.no-pin .work { height: auto; }
.no-pin .work-sticky { position: static; height: auto; overflow: visible; padding: var(--space-section) 0 3rem; }
.no-pin .work-track { overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 1rem; }
.no-pin .work-card { scroll-snap-align: start; }
.no-pin .work-progress { display: none; }

/* ============ services ============ */
.services { padding: var(--space-section) var(--gutter); }
.service-grid {
  list-style: none; margin-top: 3rem;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
.service {
  background: var(--bg); padding: clamp(1.4rem, 3vw, 2.4rem);
  display: grid; gap: .8rem; align-content: start;
  transition: background .3s;
}
.service:hover { background: var(--bg-raise); }
.service-num { font-family: var(--mono); color: var(--accent); font-size: .8rem; }
.service h3 { font-size: 1.35rem; font-weight: 800; text-transform: lowercase; }
.service p { color: var(--ink-dim); font-size: .96rem; }
.service-tag { font-family: var(--mono); font-size: .78rem; color: var(--ink); border-top: 1px solid var(--line); padding-top: .9rem; margin-top: .4rem; }

/* ============ process ============ */
.process { padding: 0 var(--gutter) var(--space-section); }
.steps { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 2.4rem; }
.step { border-top: 1px solid var(--line); padding-top: 1.2rem; }
.step-num {
  font-weight: 900; font-size: 2.6rem; color: transparent;
  -webkit-text-stroke: 1px var(--accent); display: block; line-height: 1;
}
.step h3 { margin-top: .7rem; font-size: 1.15rem; font-weight: 800; text-transform: lowercase; }
.step p { color: var(--ink-dim); font-size: .95rem; margin-top: .35rem; }

/* ============ pricing ============ */
.pricing {
  padding: var(--space-section) var(--gutter);
  background: var(--bg-raise); border-block: 1px solid var(--line);
}
.price-hero { max-width: 56rem; }
.price-sub { color: var(--ink-dim); margin-top: 1.6rem; max-width: 40rem; }
.price-points { list-style: none; margin: 1.8rem 0 2.4rem; display: grid; gap: .55rem; }
.price-points li { padding-left: 1.4rem; position: relative; color: var(--ink); }
.price-points li::before { content: "✦"; position: absolute; left: 0; color: var(--accent); font-size: .8rem; top: .25rem; }

/* ============ about ============ */
.about { padding: var(--space-section) var(--gutter); }
.about-inner { max-width: 46rem; display: grid; gap: 1.4rem; }
.about-inner p { color: var(--ink-dim); font-size: clamp(1.02rem, .92rem + .5vw, 1.2rem); }
.about-inner .section-title { margin-bottom: .6rem; }

/* ============ contact ============ */
.contact {
  padding: var(--space-section) var(--gutter);
  border-top: 1px solid var(--line);
  background:
    radial-gradient(60rem 30rem at 80% 120%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 70%),
    var(--bg);
}
.contact-inner { display: grid; gap: 1.6rem; justify-items: start; }
.contact-sub { color: var(--ink-dim); max-width: 34rem; font-size: 1.1rem; }
.contact-actions { display: flex; gap: 1rem; flex-wrap: wrap; }
.contact-note { font-family: var(--mono); font-size: .8rem; color: var(--ink-dim); }

/* ---------- enquiry form ---------- */
.contact-grid {
  width: 100%; margin-top: 1.4rem;
  display: grid; gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: minmax(0, 1.35fr) minmax(0, .65fr);
  align-items: start;
}
.enquiry { display: grid; gap: 1.1rem; max-width: 42rem; }
.field { display: grid; gap: .45rem; }
.field-row { display: grid; gap: 1.1rem; grid-template-columns: 1fr 1fr; }
.enquiry label {
  font-family: var(--mono); font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-dim);
}
.req { color: var(--accent); }
.opt { text-transform: none; letter-spacing: 0; opacity: .62; }
.enquiry input, .enquiry textarea {
  font: inherit; font-size: 1rem; color: var(--ink);
  background: var(--bg-raise);
  border: 1px solid var(--line); border-radius: 3px;
  padding: .85rem 1rem; width: 100%;
  transition: border-color .25s var(--ease-out), background-color .25s var(--ease-out);
}
.enquiry textarea { resize: vertical; min-height: 5.5rem; line-height: 1.55; }
.enquiry input::placeholder, .enquiry textarea::placeholder { color: color-mix(in srgb, var(--ink-dim) 62%, transparent); }
.enquiry input:hover, .enquiry textarea:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.enquiry input:focus-visible, .enquiry textarea:focus-visible {
  border-color: var(--accent); background: var(--bg-card); outline-offset: 1px;
}
.enquiry [aria-invalid="true"] { border-color: #c9705f; }
.err { font-family: var(--mono); font-size: .74rem; color: #e08a78; }
.enquiry button[type="submit"] { justify-self: start; margin-top: .3rem; }
.enquiry button[disabled] { opacity: .55; pointer-events: none; }
.form-note { font-family: var(--mono); font-size: .74rem; line-height: 1.7; color: var(--ink-dim); max-width: 34rem; }
.form-status { font-family: var(--mono); font-size: .82rem; min-height: 1.2em; }
.form-status[data-state="ok"] { color: var(--accent); }
.form-status[data-state="err"] { color: #e08a78; }
/* honeypot — off-canvas, never announced, never focusable in the tab order */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.contact-direct { display: grid; gap: .55rem; justify-items: start; padding-top: .4rem; }
.direct-label {
  font-family: var(--mono); font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-dim); margin-bottom: .2rem;
}
.direct-line {
  font-size: 1.02rem; text-decoration: none; border-bottom: 1px solid var(--line);
  padding-bottom: .15rem; transition: color .25s var(--ease-out), border-color .25s var(--ease-out);
  word-break: break-word;
}
.direct-line:hover { color: var(--accent); border-color: var(--accent); }
.contact-direct .contact-note { margin-top: .8rem; max-width: 22rem; line-height: 1.75; }

/* ============ footer ============ */
.site-foot {
  padding: 3rem var(--gutter) 4rem; border-top: 1px solid var(--line);
  display: grid; gap: .5rem; font-size: .9rem; color: var(--ink-dim);
}
.foot-mark { font-weight: 900; color: var(--ink); letter-spacing: .04em; }
.foot-mark span { color: var(--accent); margin-left: .35ch; }
.site-foot a { color: var(--ink-dim); }
.site-foot a:hover { color: var(--accent); }
.foot-fine { font-size: .78rem; margin-top: 1rem; }

/* ============ reveals ============ */
.reveal {
  opacity: 0; transform: translateY(var(--travel)) scale(.965);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.motion-armed .reveal.revealed { opacity: 1; transform: none; }
/* failsafe + no-JS + reduced-motion: never hide content */
.no-motion .reveal, html:not(.motion-armed) .reveal { opacity: 1; transform: none; clip-path: none; }

/* section titles: masked wipe reveal */
.section-title.reveal, .display-md.reveal {
  clip-path: inset(-8% -4% 104% -4%);
  transform: translateY(calc(var(--travel) * .55)) scale(.97);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out),
              clip-path 1500ms var(--ease-out);
}
.motion-armed .section-title.reveal.revealed, .motion-armed .display-md.reveal.revealed {
  clip-path: inset(-8% -4% -12% -4%);
}

/* staggered grids — wider steps so the sequence reads as a cascade */
.service.reveal:nth-child(2), .step.reveal:nth-child(2) { transition-delay: 130ms; }
.service.reveal:nth-child(3), .step.reveal:nth-child(3) { transition-delay: 260ms; }
.service.reveal:nth-child(4) { transition-delay: 390ms; }

/* ============ scroll-linked wordmark band ============ */
.band { overflow: hidden; border-block: 1px solid var(--line); padding: clamp(1.6rem, 4vw, 3.2rem) 0; }
.band-text {
  white-space: nowrap; width: max-content; will-change: transform;
  font-weight: 900; font-stretch: 92%; line-height: 1;
  font-size: clamp(4rem, 2rem + 10vw, 11rem);
  color: transparent; -webkit-text-stroke: 1px #3a352d;
  letter-spacing: -0.01em;
}
.band-text i {
  font-style: normal; -webkit-text-stroke: 0; color: var(--accent);
  font-size: .32em; vertical-align: .38em; margin: 0 .3em;
}

/* ticker velocity skew is applied to the wrapper by JS */
.ticker { will-change: transform; }

/* ============ responsive ============ */
@media (max-width: 980px) {
  .contact-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
  .site-head nav { display: none; }
  .hero-foot { gap: 1.1rem; font-size: .78rem; }
  .scroll-cue { display: none; }
  .work-head { flex-direction: column; align-items: start; }
  .work-card { flex-basis: 84vw; }
  .field-row { grid-template-columns: minmax(0, 1fr); }
}

/* ============ reduced motion ============ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker-track { animation: none; }
  .cue-line::after { animation: none; }
  .reveal, .display .line > span { transition: none !important; }
  /* the amplified motion added 30 Aug is switched off here too, wholesale —
     bigger defaults must never mean a bigger accessibility cost */
  .work-card { transform: none !important; opacity: 1 !important; }
  .shot img, .work-card:hover .shot { transform: none !important; }
}

/* ---------- portfolio cards are explorable, not decorative ----------
   Ashton's point 1 Sept: a screenshot proves nothing, a working site does.
   Each card is now a link into the real demo, so a prospect can click in and
   browse what they would actually be buying. The cue only appears on
   hover/focus so the grid stays calm at rest, but it is always in the
   accessibility tree — a keyboard or screen-reader user gets the same
   affordance a mouse user does. */
.demo-link { display: block; text-decoration: none; color: inherit; position: relative; }
.demo-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 16px; }
.demo-cue {
  display: block; margin-top: .7rem;
  font-family: var(--mono); font-size: .74rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent);
  opacity: 0; transform: translateY(4px);
  transition: opacity .35s var(--ease-out), transform .35s var(--ease-out);
}
.demo-link:hover .demo-cue,
.demo-link:focus-visible .demo-cue { opacity: 1; transform: none; }
/* the whole card lifts, so the click target reads as one object */
.demo-link:hover .shot { border-color: var(--accent); transform: translateY(-16px) scale(1.02); }
.demo-link:hover .shot img { transform: scale(1.09); }
/* Non-client concept cards (18 Sep 2026, Card A interim close — Genji, CTO):
   these 5 cards no longer link anywhere (the go-live exposure fix strips
   their <a> down to a static <div class="demo-link demo-link-static">), so
   they must stop LOOKING clickable — no hover-lift, no cursor change, and
   the "concept preview" cue reads as a permanent static label rather than a
   hover-revealed invitation to click through. */
.demo-link-static { cursor: default; }
.demo-link-static:hover .shot,
.demo-link-static:focus-visible .shot { border-color: inherit; transform: none; }
.demo-link-static:hover .shot img { transform: none; }
.demo-link-static .demo-cue { opacity: .6; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .demo-cue { opacity: 1; transform: none; transition: none; }
  .demo-link:hover .shot, .demo-link:hover .shot img { transform: none; }
}
/* Touch devices never hover: show the cue permanently so the card still
   announces itself as explorable. */
@media (hover: none) {
  .demo-cue { opacity: 1; transform: none; }
}

/* ============ touch targets ============
   Measured at 375px on 1 Sept 2026: the header CTA was 40px tall and the two
   contact links — the email address and the phone number, i.e. the actual
   conversion actions — were 16px. Under the 44px floor, on a site whose whole
   pitch is that a bad website loses you work.

   Two deliberate choices:
   - `(pointer: coarse)` rather than a width breakpoint, because a narrow window
     on a desktop is not a touch device and does not need this.
   - The contact links grow their HIT AREA via a pseudo-element, not padding.
     They are inline anchors with a border-bottom underline; padding them would
     push that underline away from the text and break the treatment. This moves
     no pixels at all — it only makes the tappable box 44px tall. */
@media (pointer: coarse) {
  .direct-line { position: relative; }
  .direct-line::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
  }
  .site-foot a { position: relative; }
  .site-foot a::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: 50%; transform: translateY(-50%); height: 44px;
  }
  .head-cta { min-height: 44px; display: inline-flex; align-items: center; }
}

/* ============ footer sitemap (18 Sep 2026 — local-search pages) ============
   Every town, service and case-study page is one click from any footer. */
.foot-grid {
  display: grid; gap: 2.4rem 3rem;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  align-items: start; margin-bottom: 1rem;
}
.foot-brand { display: grid; gap: .5rem; }
.foot-col { display: grid; gap: .55rem; justify-items: start; }
.foot-col a { text-decoration: none; font-size: .9rem; line-height: 1.35; transition: color .2s; }
.foot-label {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .3rem;
}
@media (max-width: 980px) { .foot-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .foot-brand { grid-column: 1 / -1; } }
@media (max-width: 560px) { .foot-grid { grid-template-columns: minmax(0, 1fr); } }

/* ============ home page strips — areas + what we build ============
   Hairline ledgers, not cards: the home page already has one card grid (work)
   and does not need a second. Type does the work. */
.strip { padding: var(--space-section) var(--gutter); border-top: 1px solid var(--line); }
.strip-head { display: flex; align-items: end; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-bottom: 2.2rem; }
.strip-head p { color: var(--ink-dim); max-width: 28rem; font-size: .95rem; }
.strip-areas { background: var(--bg-raise); }
.strip-areas .link-ledger { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(1.5rem, 4vw, 4rem); border-top: 0; }
.strip-areas .link-ledger li:nth-child(-n+2) a { border-top: 1px solid var(--line); }
.link-ledger { list-style: none; border-top: 1px solid var(--line); }
.link-ledger a {
  display: grid; grid-template-columns: 1fr auto auto; gap: 1.5rem; align-items: baseline;
  padding: clamp(1rem, 2.2vw, 1.6rem) 0; border-bottom: 1px solid var(--line);
  text-decoration: none; color: var(--ink);
  font-weight: 900; font-stretch: 92%; letter-spacing: -.015em; line-height: 1;
  font-size: clamp(1.45rem, 1rem + 2.4vw, 3.2rem); text-transform: uppercase;
  transition: color .25s var(--ease-out);
}
.link-ledger a em { font-family: var(--serif); font-style: italic; font-weight: 380; text-transform: lowercase; letter-spacing: 0; font-size: 1.02em; color: var(--ink); transition: color .25s; }
.link-ledger a:hover, .link-ledger a:hover em { color: var(--accent); }
.link-ledger .tag { font-family: var(--mono); font-size: .74rem; letter-spacing: .14em; color: var(--ink-dim); font-weight: 400; text-transform: uppercase; }
.link-ledger .arr { font-weight: 400; color: var(--accent); transform: translateX(-6px); opacity: 0; transition: transform .35s var(--ease-out), opacity .35s; font-size: .7em; }
.link-ledger a:hover .arr { transform: none; opacity: 1; }
.strip-areas .link-ledger a { font-size: clamp(1.3rem, .9rem + 1.8vw, 2.5rem); }
@media (max-width: 760px) {
  .strip-areas .link-ledger { grid-template-columns: minmax(0, 1fr); }
  .strip-areas .link-ledger li:nth-child(2) a { border-top: 0; }
  .link-ledger a { grid-template-columns: 1fr auto; }
  .link-ledger .arr { display: none; }
}
@media (prefers-reduced-motion: reduce) { .link-ledger .arr { opacity: 1; transform: none; transition: none; } }

/* ============ analytics consent (consent.js) ============ */
.consent {
  position: fixed; z-index: 95; right: var(--gutter); bottom: clamp(.9rem, 2vw, 1.6rem);
  max-width: 26rem; display: grid; gap: .9rem;
  padding: 1.1rem 1.2rem; border: 1px solid var(--line); border-radius: 14px;
  background: color-mix(in srgb, var(--bg-card) 88%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .7);
  font-size: .92rem; line-height: 1.5; color: var(--ink-dim);
  opacity: 0; transform: translateY(18px);
  transition: opacity .45s var(--ease-out), transform .6s var(--ease-out);
}
.consent.is-in { opacity: 1; transform: none; }
.consent a { color: var(--ink); text-underline-offset: .2em; }
.consent-actions { display: flex; gap: .6rem; justify-content: flex-end; }
.consent .btn { padding: .6rem 1.1rem; font-size: .9rem; font-family: inherit; cursor: pointer; }
.consent .btn-solid { border: 1px solid transparent; }
.consent .btn-ghost { background: transparent; }
@media (max-width: 560px) {
  .consent { left: var(--gutter); max-width: none; }
  .consent-actions .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) { .consent { transition: none; transform: none; } }
