/* ───────────────────────────────────────────────────────────────────────────
   Design tokens

   Two themes from one set of names. Components reference the semantic tokens
   (--canvas, --surface, --ink, --brand …) and never a raw hex, so the whole
   site re-themes from this block alone.

   The --color-* names further down are a compatibility layer: existing rules
   were written against the old palette, so those names now alias the semantic
   tokens rather than carrying values of their own.
   ─────────────────────────────────────────────────────────────────────────── */
:root {
    color-scheme: light;

    /* Brand. Deepened from the web-safe #008080, which read cheap beside the
       logo. Neon #39FF14 is retired: a glowing lime CTA is the loudest single
       signal that a B2B product is not a premium one. */
    --brand: #0E6E63;
    --brand-strong: #0A544B;
    --brand-contrast: #FFFFFF;
    --brand-soft: rgba(14, 110, 99, 0.09);

    /* Large brand-coloured areas — the phone screen, the featured plan, the
       "good" comparison card. Kept separate from --brand because the value
       that is right for a 16px tick is not the value that is right for a
       600px panel, and that difference only shows up in dark. */
    --brand-panel: var(--brand);
    --brand-panel-strong: var(--brand-strong);
    --brand-panel-ink: var(--brand-contrast);

    /* Surfaces. Warm off-white rather than pure white — paper, not screen. */
    --canvas: #FBFAF8;
    --surface: #FFFFFF;
    --surface-sunken: #F4F2EE;

    --ink: #0F1115;
    --ink-muted: #656E7B;
    --ink-faint: #98A1AE;
    --hairline: #E7E3DC;

    /* Form errors and the modal scrim. */
    --danger: #B3261E;
    --scrim: rgba(16, 18, 21, 0.44);

    /* Depth, layered and quiet. The old buttons carried
       0 4px 15px rgba(0,0,0,.3) plus a lime glow at .4 alpha — that is stage
       lighting, not elevation. */
    --shadow-1: 0 1px 2px rgba(16, 18, 21, 0.04);
    --shadow-2: 0 8px 24px rgba(16, 18, 21, 0.06);
    --shadow-3: 0 24px 56px rgba(16, 18, 21, 0.10);

    /* One family. Poppins 700 headings were friendly rather than considered,
       and dropping the second family removes a render-blocking request. */
    --font-heading: 'Inter', system-ui, sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;
    --tracking-tight: -0.022em;
    --tracking-snug: -0.014em;
    --tracking-wide: 0.08em;

    /* Crisp, not bubbly. 32px radii next to heavy shadows read as a toy. */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;
    --radius-full: 9999px;

    --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);

    /* Spacing scale — every step is a multiple of 4px. Reach for a step rather
       than inventing a value; the odd 0.6/0.8/1.2rem one-offs this replaced
       were what made the rhythm look approximate. */
    --space-1: 0.25rem;
    /* 4px  */
    --space-2: 0.5rem;
    /* 8px  */
    --space-3: 0.75rem;
    /* 12px */
    --space-4: 1rem;
    /* 16px */
    --space-5: 1.5rem;
    /* 24px */
    --space-6: 2rem;
    /* 32px */
    --space-7: 2.5rem;
    /* 40px */
    --space-8: 3rem;
    /* 48px */
    --space-9: 4rem;
    /* 64px */

    /* Sized against the type scale, not fixed, and fluid so it does not need a
       media query to stop being silly on a phone.

       Note this is padding on BOTH sides, so adjacent sections give twice this
       between them: 72px each meant 144px of nothing between one idea and the
       next, which read as the page having ended. 52px at desktop gives 104px —
       still a clear break, no longer a gap. */
    --section-spacing: clamp(2.25rem, 3.6vw, 3.25rem);
    /* 36px → 52px */

    /* One interior padding for every card, so a feature card and a pricing
       card sit on the same grid instead of 3rem / 2.5rem / 2rem apiece. */
    --card-padding: var(--space-6);

    /* ── Compatibility layer ───────────────────────────────────────────────
       The old palette names, now aliases. Every rule written against them
       re-themes for free, and there is still exactly one place a colour is
       decided. New rules should use the semantic tokens above. */
    --color-primary: var(--brand);
    --color-primary-dark: var(--brand-strong);
    --color-bg-white: var(--surface);
    --color-bg-light: var(--surface-sunken);
    --color-bg-dark: var(--ink);
    --color-text-dark: var(--ink);
    --color-text-muted: var(--ink-muted);
    --color-border: var(--hairline);
    /* Was neon lime with a dark-green label on top. The accent is the brand
       now, so anything that used it as a fill gets a white label. */
    --color-accent: var(--brand);
    --color-accent-hover: var(--brand-strong);
    --color-accent-text: var(--brand-contrast);
    --shadow-sm: var(--shadow-1);
    --shadow-md: var(--shadow-2);
    --shadow-lg: var(--shadow-3);
}

/* ── Dark theme ────────────────────────────────────────────────────────────
   Not the light palette inverted. On a near-black canvas the brand has to
   emit light rather than absorb it, so the teal lifts to #2DD4BF; surfaces
   are raised planes rather than white; and hairlines become translucent so
   they read as edges on glass instead of drawn lines.
   ────────────────────────────────────────────────────────────────────────── */
:root[data-theme="dark"] {
    color-scheme: dark;

    --brand: #2DD4BF;
    --brand-strong: #5EEAD4;
    /* Label sits ON the luminous fill, so it must be the dark one. */
    --brand-contrast: #04211E;
    --brand-soft: rgba(45, 212, 191, 0.12);

    /* A flooded #2DD4BF panel on a near-black page is a lightbox — it drags
       the eye off everything else and the copy on it has to be dark, which
       inverts the whole reading order. Panels go deep; the luminous teal is
       kept for detail. */
    --brand-panel: #0D3B36;
    --brand-panel-strong: #072A26;
    --brand-panel-ink: #E4FFF9;

    --canvas: #0A0C10;
    --surface: #12151B;
    --surface-sunken: #171B23;

    --ink: #F2F4F7;
    --ink-muted: #9BA3AF;
    --ink-faint: #6C7681;
    --hairline: rgba(255, 255, 255, 0.09);

    /* #B3261E on a near-black panel fails contrast; this reads as the same
       colour but survives the background. The scrim goes deeper because the
       page behind it is already dark. */
    --danger: #FF8A80;
    --scrim: rgba(0, 0, 0, 0.66);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-2: 0 12px 32px rgba(0, 0, 0, 0.45);
    --shadow-3: 0 24px 64px rgba(0, 0, 0, 0.55);
}

/* Base Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    font-size: 16px;
}

body {
    font-family: var(--font-body);
    font-weight: 400;
    /* Base for copy with no size of its own; the root stays 16px so rem
       spacing is unaffected. */
    font-size: 0.75rem;
    color: var(--color-text-dark);
    background-color: var(--canvas);
    line-height: 1.6;
    overflow-x: hidden;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: var(--font-heading);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: var(--tracking-tight);
    text-wrap: balance;
    margin-bottom: 1rem;
    color: var(--color-text-dark);
}

h1 {
    font-size: clamp(1.875rem, 3.75vw, 3rem);
    letter-spacing: var(--tracking-tight);
}

h2 {
    font-size: clamp(1.5rem, 3vw, 2.25rem);
    letter-spacing: var(--tracking-tight);
    text-align: center;
    /* Deliberately NOT derived from --section-spacing any more. Tightening the
       gap between sections should not also pull a heading down onto its own
       content — that space is what makes the heading read as a title rather
       than a first line. It stays at roughly its old value while the gap
       between sections shrinks around it. */
    margin-bottom: clamp(1.5rem, 2.4vw, 2.25rem);
}

h3 {
    font-size: 1.125rem;
}

/* Small tracked label above a heading. Gives a section a subject before it
   gives you a statement, which is most of what makes editorial layouts read as
   considered rather than as a list of banners. */
.eyebrow {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: var(--tracking-wide);
    text-transform: uppercase;
    color: var(--brand);
    margin-bottom: var(--space-3);
}

/* A hairline is the quiet way to bound a card. The shadowed-box treatment made
   every panel shout for the same attention; now elevation is reserved for
   things that are genuinely lifted — the featured plan, an open modal. */
.comparison-card,
.testimonial-card,
.metric-card {
    border: 1px solid var(--hairline);
    box-shadow: none;
}

.testimonial-card:hover {
    border-color: color-mix(in srgb, var(--brand) 36%, var(--hairline));
    box-shadow: var(--shadow-2);
}

p {
    color: var(--color-text-muted);
    margin-bottom: 1rem;
}

a {
    text-decoration: none;
    color: inherit;
    transition: var(--transition);
}

ul {
    list-style: none;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

button {
    font-family: inherit;
    cursor: pointer;
    border: none;
    background: none;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

.text-center {
    text-align: center;
}

.section {
    padding: var(--section-spacing) 0;
}

/* The header is fixed, so a nav link would drop the section's heading behind
   it — the reader lands on a section whose title they cannot see. Clears the
   header plus a little air. */
section[id] {
    scroll-margin-top: calc(var(--space-9) + var(--space-5));
}

.bg-light {
    background-color: var(--color-bg-light);
}

.bg-primary {
    background-color: var(--brand-panel);
    color: var(--brand-panel-ink);
}

.bg-primary p,
.bg-primary h2 {
    color: var(--brand-panel-ink);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.875rem 2rem;
    border-radius: var(--radius-full);
    font-weight: 500;
    font-size: 0.75rem;
    letter-spacing: var(--tracking-snug);
    transition: var(--transition);
    text-align: center;
    gap: 0.5rem;
}

.btn-primary {
    background-color: var(--brand);
    color: var(--brand-contrast);
    font-weight: 600;
    box-shadow: var(--shadow-1);
}

.btn-primary:hover {
    background-color: var(--brand-strong);
    transform: translateY(-1px);
    box-shadow: var(--shadow-2);
}

.btn-secondary {
    background-color: var(--surface);
    color: var(--ink);
    border: 1px solid var(--hairline);
    box-shadow: var(--shadow-1);
}

.btn-secondary:hover {
    border-color: var(--ink-faint);
    background-color: var(--surface-sunken);
}

.btn-teal {
    background-color: var(--brand);
    color: var(--brand-contrast);
    border: none;
    box-shadow: var(--shadow-1);
}

.btn-teal:hover {
    background-color: var(--brand-strong);
    color: var(--brand-contrast);
    transform: translateY(-1px);
    box-shadow: var(--shadow-2);
}

.btn-dark {
    background-color: var(--ink);
    color: var(--canvas);
    border: 1px solid var(--ink);
    box-shadow: var(--shadow-1);
}

.btn-dark:hover {
    background-color: var(--ink-muted);
    border-color: var(--ink-muted);
    transform: translateY(-1px);
    box-shadow: var(--shadow-2);
}

.btn-outline {
    border: 1px solid currentColor;
    color: var(--brand-contrast);
}

.btn-outline:hover {
    background-color: var(--brand-contrast);
    color: var(--color-primary);
}

/* Login Button Styles */
.header-cta {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.header-cta .btn {
    padding: var(--space-3) var(--space-5);
    font-size: 0.6875rem;
    white-space: nowrap;
}

.btn-login {
    font-weight: 600;
    color: var(--color-text-dark);
    font-size: 0.7125rem;
    transition: var(--transition);
    text-decoration: none;
}

.btn-login:hover {
    color: var(--color-primary);
}

/* Ensure mobile compatibility */
@media (max-width: 768px) {
    .header-cta {
        display: none; /* Keeps the header clean on mobile as per your existing logic */
    }
    
    /* Optional: Add login to the mobile nav menu */
    .nav.active ul {
        border-bottom: 1px solid var(--color-border);
        margin-bottom: 1rem;
        padding-bottom: 1rem;
    }
}

/* ── Theme switch ──────────────────────────────────────────────────────────
   One control, two icons, only the relevant one rendered. Sized to a 40px
   target so it is comfortable on touch without becoming a third button in a
   header that already has three.
   ────────────────────────────────────────────────────────────────────────── */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    margin-left: var(--space-2);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-full);
    background-color: transparent;
    color: var(--ink-muted);
    transition: var(--transition);
}

.theme-toggle:hover {
    color: var(--ink);
    border-color: var(--ink-faint);
    background-color: var(--surface-sunken);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
}

.theme-toggle__icon {
    width: 17px;
    height: 17px;
}

/* Show the destination, not the current state: in light you see the moon you
   are about to switch to. */
.theme-toggle__sun {
    display: none;
}

:root[data-theme="dark"] .theme-toggle__sun {
    display: block;
}

:root[data-theme="dark"] .theme-toggle__moon {
    display: none;
}

/* Header & Nav */
.header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background-color: color-mix(in srgb, var(--canvas) 82%, transparent);
    backdrop-filter: blur(10px);
    z-index: 1000;
    border-bottom: 1px solid transparent;
    transition: var(--transition);
    padding: 1.25rem 0;
}

.header.sticky {
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-sm);
}

.nav-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    font-family: var(--font-heading);
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--color-primary);
}

.logo span {
    color: var(--color-accent);
    -webkit-text-stroke: 1px var(--color-text-dark);
    text-stroke: 1px var(--color-text-dark);
}

.nav ul {
    display: flex;
    gap: 2rem;
}

.nav a {
    font-weight: 500;
    color: var(--color-text-muted);
}

.nav a:hover {
    color: var(--color-primary);
}

/* The primary navigation control on a phone, and it was a bare 21px glyph —
   the hit area was the icon itself. Sized to a proper target; the box stays
   invisible so nothing changes visually. */
.menu-toggle {
    display: none;
    font-size: 1.125rem;
    color: var(--color-text-dark);
    width: 44px;
    height: 44px;
    align-items: center;
    justify-content: center;
    margin-right: calc(var(--space-3) * -1);
}

/* Discrete controls that were smaller than a fingertip. Padding widens the
   target without moving the text.

   Deliberately not applied to links inside prose — a URL in a legal paragraph
   or the wordmark in the hero sentence. WCAG 2.5.8 exempts inline targets, and
   padding them would open up the line spacing of the paragraph around them. */
@media (max-width: 768px) {

    .footer-links a,
    .footer-col a,
    .nav ul li a {
        display: inline-block;
        padding-block: var(--space-2);
    }

    .social-links a {
        width: 40px;
        height: 40px;
    }

    /* The header wordmark is a nav target, not prose: it goes home. */
    .header .logo {
        min-height: 44px;
        align-items: center;
    }
}

/* Animation Classes */
.fade-up {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.8s ease, transform 0.8s ease;
}

.fade-up.visible {
    opacity: 1;
    transform: translateY(0);
}

.delay-1 {
    transition-delay: 0.1s;
}

.delay-2 {
    transition-delay: 0.2s;
}

.delay-3 {
    transition-delay: 0.3s;
}

/* 1. Hero Section */
.hero {
    padding: calc(var(--section-spacing) + 80px) 0 var(--section-spacing);
    overflow: hidden;
    position: relative;
}

.hero::before {
    content: '';
    position: absolute;
    top: -50%;
    right: -20%;
    width: 800px;
    height: 800px;
    background: radial-gradient(circle, var(--brand-soft) 0%, transparent 70%);
    border-radius: 50%;
    z-index: -1;
}

.hero-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    align-items: center;
}

.hero-content h1 {
    margin-bottom: 1.5rem;
}

.hero-content .subtext {
    font-size: 0.8438rem;
    font-weight: 400;
    margin-bottom: 2.5rem;
    max-width: 500px;
}

.hero-actions {
    display: flex;
    gap: 1rem;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

.trust-line {
    display: flex;
    /* start, not center: the label wraps to two lines on a phone, and a centred
       tick drifts to the middle of them. */
    align-items: start;
    gap: var(--space-2);
    font-size: 0.6875rem;
    color: var(--color-text-muted);
    font-weight: 500;
}

.trust-line i {
    margin-top: 0.15em;
    flex: 0 0 auto;
}

.trust-line i {
    color: var(--color-primary);
}

.hero-visual {
    position: relative;
    display: flex;
    justify-content: center;
}

/* ── The tap ───────────────────────────────────────────────────────────────
   Your card leaving your phone and arriving in someone else's. Two devices
   risk reading as a diagram of small objects, so the sender is deliberately
   dominant and carries a real card: the frame is a product shot first and an
   explanation second. The receiver is smaller, set back and dimmer, which is
   also true to the story — their phone is incidental, and they installed
   nothing.
   ────────────────────────────────────────────────────────────────────────── */
/* Explicit positions rather than a centred flex row. Centring both and nudging
   the receiver with right:0 put its left half behind the sender, so its label
   was cut mid-word, and left no gap for the signal to travel through. The two
   are now placed against the scene's own edges with a measured gap between. */
.tap-scene {
    position: relative;
    width: 100%;
    max-width: 26rem;
    /* Sender height plus the receiver's drop, since both are out of flow. */
    aspect-ratio: 26 / 31;
    /* The tilts push each phone a little past its own box; without this the
       rotated corners sit outside the scene and get clipped by .hero. */
    padding-inline: 0.75rem;
}

.tap-phone {
    position: relative;
    border-radius: 1.6rem;
    padding: 0.5rem 0.42rem;
    background: linear-gradient(160deg, #2A2F37 0%, #14171C 46%, #23272E 100%);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, .55),
        inset 0 0 0 1px rgba(255, 255, 255, .10),
        var(--shadow-3);
}

/* Earpiece slot, same detail as the gallery handsets. */
.tap-phone::before {
    content: '';
    position: absolute;
    top: 0.86rem;
    left: 50%;
    transform: translateX(-50%);
    width: 1.9rem;
    height: 0.18rem;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, .22);
    z-index: 2;
}

/* Percentages, not rem. Fixed widths only agreed at the two sizes they were
   written for: between about 780px and 1000px the column narrowed while the
   phones did not, and they overlapped by 12px. */
.tap-phone--send {
    position: absolute;
    left: 0;
    top: 0;
    width: 56%;
    z-index: 3;
    transform: rotate(-3deg);
}

.tap-phone--send img {
    display: block;
    width: 100%;
    aspect-ratio: 9 / 16;
    object-fit: cover;
    object-position: top center;
    border-radius: 1.18rem;
    background: var(--surface-sunken);
}

/* Set back and smaller: it is the other person's phone, not the product. It
   clears the sender entirely — 14.5 + 2 gap + 9.5 = 26rem — so nothing of its
   label is hidden. */
.tap-phone--receive {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 36.5%;
    z-index: 1;
    transform: rotate(5deg);
}

.tap-received {
    aspect-ratio: 9 / 16;
    border-radius: 1.18rem;
    background: linear-gradient(170deg, var(--surface) 0%, var(--surface-sunken) 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-4);
    text-align: center;
}

.tap-received strong {
    font-size: 0.75rem;
    color: var(--ink);
    letter-spacing: var(--tracking-snug);
}

.tap-received__meta {
    font-size: 0.6875rem;
    color: var(--ink-muted);
}

.tap-received__tick {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: var(--brand);
    color: var(--brand-contrast);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    margin-bottom: var(--space-1);
}

/* The signal. Three arcs opening outward from the sender's edge, staggered so
   one is always mid-flight. */
/* Centred on the gap between the two phones, and above both — at z-index 2 it
   sat behind the sender and never appeared at all. */
/* Centred on the seam between the two phones and above both. It is wider
   than the gap on purpose — the arcs should look like they are leaving the
   sender's edge, not sitting in a corridor. */
.tap-signal {
    position: absolute;
    left: 59.75%;
    bottom: 27%;
    transform: translateX(-50%);
    width: 14%;
    aspect-ratio: 1;
    z-index: 4;
    pointer-events: none;
}

/* The QR the sender is holding out, and the scan finding it.
   Replaces .tap-arc below, which drew an NFC signal travelling between two
   phones — an interaction the product does not have. */
.tap-qr {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border-radius: 22%;
    background: #fff;
    color: #0f172a;
    box-shadow: 0 10px 30px rgba(9, 11, 15, .22);
    /* Clips the sweep below to the tile. */
    overflow: hidden;
}

.tap-qr i {
    /* Scales with the tile, which is itself a percentage of the scene, so the
       glyph holds its proportion from a phone up to a wide desktop hero.
       Kept to roughly two thirds of the tile: a code printed edge to edge has no
       quiet zone, and a real one that looked like this would not scan. */
    font-size: clamp(.9rem, 2.6vw, 2rem);
    line-height: 1;
}

/* One pass down the code, the way a camera locks on — not a pulse. */
.tap-qr__beam {
    position: absolute;
    left: 0;
    right: 0;
    height: 18%;
    background: linear-gradient(180deg, transparent, rgba(16, 185, 129, .55), transparent);
    animation: tapScan 2.6s cubic-bezier(.4, 0, .2, 1) infinite;
}

@keyframes tapScan {
    0% { top: -20%; opacity: 0; }
    12% { opacity: 1; }
    70% { opacity: 1; }
    85% { top: 100%; opacity: 0; }
    100% { top: 100%; opacity: 0; }
}

/* Superseded by .tap-qr above and no longer in the markup. Kept rather than
   dropped: the arcs are a good NFC visual, and NFC is still a product — a card
   or tag tapped against a phone. If that scene is ever built, this is the
   animation it wants. */
.tap-arc {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid var(--brand);
    /* Only the leading quadrant is drawn, so it reads as a signal travelling
       rather than a ring pulsing in place. */
    clip-path: polygon(50% 50%, 100% 0, 100% 100%);
    opacity: 0;
    animation: tapSignal 2.8s cubic-bezier(.25, .6, .3, 1) infinite;
}

.tap-arc:nth-child(2) {
    animation-delay: .55s;
}

.tap-arc:nth-child(3) {
    animation-delay: 1.1s;
}

@keyframes tapSignal {
    0% {
        transform: scale(.35);
        opacity: 0;
    }

    18% {
        opacity: .85;
    }

    70% {
        opacity: 0;
    }

    100% {
        transform: scale(1.5);
        opacity: 0;
    }
}

/* A still frame says the same thing: the code is simply there to be read. */
@media (prefers-reduced-motion: reduce) {
    .tap-qr__beam {
        animation: none;
        top: 41%;
        opacity: .5;
    }

    .tap-arc {
        animation: none;
        opacity: .5;
        transform: scale(1);
    }

    .tap-arc:nth-child(2) {
        transform: scale(1.2);
        opacity: .3;
    }

    .tap-arc:nth-child(3) {
        transform: scale(1.4);
        opacity: .16;
    }
}

/* 2. Trust Bar */
.trust-bar {
    padding: var(--space-8) 0;
    background-color: var(--color-bg-white);
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.trust-bar p {
    text-align: center;
    font-size: 0.6875rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 2rem;
}

.logos-row {
    display: flex;
    /* center, not space-between. With six items that wrap, space-between left
       the final row aligned hard left with a single orphaned icon and a gap
       across the rest of the row. */
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-7) var(--space-9);
    opacity: 0.6;
    filter: grayscale(100%);
}

.logos-row i {
    font-size: 1.875rem;
    transition: var(--transition);
}

.logos-row i:hover {
    filter: grayscale(0%);
    opacity: 1;
    color: var(--color-primary);
}

/* On a phone the six icons wrap five-and-one, stranding the last one centred on
   a row of its own — it reads as a missing item rather than a set. Three-up
   splits them evenly instead. Grid rather than a narrower flex gap: squeezing
   all six onto one line leaves them almost touching at 360px. */
@media (max-width: 34rem) {
    .logos-row {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        justify-items: center;
        gap: var(--space-6) var(--space-4);
    }
}

/* 3. Problem Section */
.problem-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
}

.comparison-card {
    padding: var(--card-padding);
    border-radius: var(--radius-lg);
}

.comparison-card h3 {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2rem;
    font-size: 1.3125rem;
}

.card-bad {
    background-color: var(--color-bg-light);
    border: 1px solid var(--color-border);
}

.card-bad h3 i {
    color: var(--danger);
}

.card-good {
    background-color: var(--brand-panel);
    color: var(--brand-panel-ink);
    box-shadow: var(--shadow-lg);
}

.card-good h3 {
    color: var(--brand-panel-ink);
}

.card-good h3 i {
    color: var(--brand-panel-ink);
}

.card-good p {
    color: color-mix(in srgb, var(--brand-panel-ink) 88%, transparent);
}

.compare-list li {
    display: flex;
    /* start, not center: these items wrap, and a centred mark drifts to the
       middle of two lines and stops forming a column. */
    align-items: start;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    font-weight: 400;
    font-size: 0.75rem;
    line-height: 1.5;
}

.card-bad .compare-list li::before {
    content: '\f00d';
    font-family: 'Font Awesome 6 Free';
    font-weight: 900;
    color: var(--danger);
    font-size: 0.75rem;
    width: 1rem;
    flex: 0 0 auto;
}

.card-good .compare-list li::before {
    content: '\f00c';
    font-family: 'Font Awesome 6 Free';
    font-weight: 900;
    color: var(--brand-panel-ink);
    font-size: 0.75rem;
    width: 1rem;
    flex: 0 0 auto;
}

.card-good .compare-list li {
    color: color-mix(in srgb, var(--brand-panel-ink) 90%, transparent);
}

/* 4. How It Works */
.steps-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    position: relative;
    text-align: center;
}

.step-item {
    position: relative;
    z-index: 2;
}

.step-icon {
    width: 56px;
    height: 56px;
    background-color: var(--brand-soft);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.125rem;
    color: var(--color-primary);
    margin: 0 auto var(--space-4);
    box-shadow: none;
    transition: var(--transition);
}

.step-item:hover .step-icon {
    background-color: var(--brand);
    color: var(--brand-contrast);
    transform: scale(1.06);
}

.step-item h3 {
    font-size: 0.9375rem;
    margin-bottom: 0.5rem;
}

/* Arrows */
.steps-grid::after {
    content: '';
    position: absolute;
    top: 40px;
    left: 15%;
    right: 15%;
    height: 2px;
    background: dashed 2px var(--color-border);
    z-index: 1;
}

@media (max-width: 768px) {
    .steps-grid {
        grid-template-columns: 1fr;
        gap: 3rem;
    }

    .steps-grid::after {
        display: none;
    }
}

/* 5. Core Features Grid */
.features-grid {
    display: grid;
    /* Was a hard 1fr 1fr, so at 900px the two columns squeezed rather than
       stacking. The stray "# grid-template-columns" line under it was an
       attempt at this that CSS ignored as an invalid declaration. */
    grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
    gap: var(--space-6);
}

.feature-card {
    padding: var(--card-padding);
    background: var(--surface);
    border-radius: var(--radius-md);
    border: 1px solid var(--hairline);
    box-shadow: none;
    transition: var(--transition);
}

.feature-card:hover {
    /* -5px with a shadow made four cards jostle for the same attention. A
       brand-tinted edge and a small lift is enough of an answer to a cursor. */
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--brand) 34%, var(--hairline));
    box-shadow: var(--shadow-2);
}

.feature-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    /* Was rgba(0,128,128,.1) — the old teal, hardcoded, so it stayed put in
       both themes while everything around it moved. */
    background: var(--brand-soft);
    color: var(--brand);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    margin-bottom: var(--space-5);
}

.feature-card h3 {
    font-size: 0.9375rem;
    margin-bottom: var(--space-4);
}

/* Each sub-feature is a titled paragraph. Sixteen of them stacked with no
   separation was the densest block on the page; a hairline between them lets
   the eye find one without reading all four. */
.feature-card h4 {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ink);
    margin-bottom: var(--space-1);
}

.feature-card h4:not(:first-of-type) {
    border-top: 1px solid var(--hairline);
    padding-top: var(--space-4);
    margin-top: var(--space-4);
}

.feature-card h4+p {
    font-size: 0.6875rem;
    color: var(--ink-muted);
    margin-bottom: 0;
}

/* 6. Product Showcase */
.showcase-slider {
    position: relative;
    max-width: 1200px;
    margin: 0 auto;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background: var(--color-bg-light);
    /* padding: 4rem 2rem; */
    text-align: center;
}

.showcase-img {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    filter: drop-shadow(0 20px 30px rgba(0, 0, 0, 0.1));
    border-radius: var(--radius-md);
    overflow: hidden;
    border: 4px solid #fff;
}

.showcase-img img {
    width: 100%;
    border-radius: calc(var(--radius-md) - 4px);
}

/* 7. Benefits Section */
.metrics-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem;
}

.metric-card {
    text-align: center;
    padding: var(--card-padding);
}

.metric-number {
    font-family: var(--font-heading);
    font-size: 2rem;
    font-weight: 600;
    color: var(--brand);
    margin-bottom: 0.5rem;
}

.metric-text {
    font-weight: 500;
    color: var(--color-text-dark);
}

@media (max-width: 992px) {
    .metrics-grid {
        grid-template-columns: 1fr;
    }
}

/* 8. Pricing Section */
.pricing-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
    /* stretch, not center: the three plans carry 9, 11 and 14 lines, and
       centring them would leave the CTAs at three different heights — the
       thing a reader is actually trying to compare. */
    align-items: stretch;
}

.pricing-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border);
    padding: var(--space-7) var(--card-padding);
    transition: var(--transition);
    display: flex;
    flex-direction: column;
    height: 100%;
}

.pricing-card.highlight {
    background: var(--brand-panel);
    color: var(--brand-panel-ink);
    border: 1px solid var(--brand-panel);
    box-shadow: var(--shadow-lg);
    transform: scale(1.03);
}

.pricing-card.highlight p,
.pricing-card.highlight h3,
.pricing-card.highlight .price {
    color: var(--brand-panel-ink);
}

.pricing-card.highlight .feature-list li {
    color: color-mix(in srgb, var(--brand-panel-ink) 88%, transparent);
}

.pricing-card.highlight .feature-list li i {
    color: var(--brand-panel-ink);
}

/* The plan name is a label, not a heading — it sat at 15px bold, competing
   with the price right under it. Demoted to an eyebrow so the price is
   unambiguously the largest thing in the card. */
.plan-name {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--ink-muted);
    margin-bottom: var(--space-3);
}

.pricing-card.highlight .plan-name {
    color: color-mix(in srgb, var(--brand-panel-ink) 80%, transparent);
}

.price {
    font-family: var(--font-heading);
    font-size: 2.5rem;
    font-weight: 600;
    letter-spacing: var(--tracking-tight);
    margin-bottom: var(--space-2);
}

.price span {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    font-weight: 400;
    font-family: var(--font-body);
}

.pricing-desc {
    font-size: 0.6875rem;
    /* Separates "what it costs" from "who it is for". These sat flush against
       the rate line, which read as one paragraph — and worse once the
       Enterprise rate line grew to two lines on a phone. */
    margin-top: 0.5rem;
    margin-bottom: 2rem;
    min-height: 42px;
}

/* "Everything in Individual, plus" — carries the shared lines so the list
   below it only has to show what is different. */
.plan-inherits {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--ink);
    padding-top: var(--space-5);
    border-top: 1px solid var(--hairline);
    margin-bottom: var(--space-4);
}

.pricing-card.highlight .plan-inherits {
    color: var(--brand-panel-ink);
    border-top-color: color-mix(in srgb, var(--brand-panel-ink) 22%, transparent);
}

.feature-list {
    margin-bottom: var(--space-7);
    padding-top: var(--space-5);
    border-top: 1px solid var(--hairline);
    flex-grow: 1;
}

/* The inherits line already drew the rule; a second one directly under it
   would box the label in. */
.plan-inherits+.feature-list {
    padding-top: 0;
    border-top: none;
}

.pricing-card.highlight .feature-list {
    border-top-color: color-mix(in srgb, var(--brand-panel-ink) 22%, transparent);
}

/* align-items: start, not center: a wrapped line ("Unlimited Sharing
   (Whatsapp, Email, SMS, etc)") pushed its tick to the vertical middle of two
   lines, so the column of ticks stopped being a column. */
.feature-list li {
    display: flex;
    align-items: start;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    font-weight: 400;
    line-height: 1.5;
}

.feature-list li i {
    color: var(--brand);
    /* Optical alignment with the cap-height of the label beside it. */
    margin-top: 0.2em;
    flex: 0 0 auto;
}

.pricing-card .btn {
    width: 100%;
}

/* A primary button on a brand-coloured panel is the brand colour drawn on the
   brand colour. The white label still passes contrast, so a text-contrast pass
   sees nothing wrong — but the control has no shape at all, and only the drop
   shadow hints that it is a button. The featured pricing card always inverted
   here; the same treatment now covers every brand-coloured surface.

   Scoped to .btn-primary rather than .btn on purpose: .btn-outline is already
   drawn for these panels with a pale border, and filling it would flatten the
   distinction between the primary and secondary action sitting side by side. */
.pricing-card.highlight .btn-primary,
.final-cta .btn-primary,
.bg-primary .btn-primary,
.card-good .btn-primary,
.on-brand .btn-primary {
    background-color: var(--brand-panel-ink);
    color: var(--brand-panel);
}

/* Without this the hover reverts to --brand-strong and the button disappears
   again the moment it is pointed at. */
.pricing-card.highlight .btn-primary:hover,
.final-cta .btn-primary:hover,
.bg-primary .btn-primary:hover,
.card-good .btn-primary:hover,
.on-brand .btn-primary:hover {
    background-color: color-mix(in srgb, var(--brand-panel-ink) 86%, var(--brand-panel));
    color: var(--brand-panel);
}

@media (max-width: 992px) {
    .pricing-grid {
        grid-template-columns: 1fr;
    }

    .pricing-card.highlight {
        transform: none;
    }
}

/* 9. Testimonials */
.testimonials-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
}

.testimonial-card {
    background: var(--surface);
    padding: 2.5rem;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--color-border);
}

.quote-icon {
    color: var(--color-primary);
    opacity: 0.2;
    font-size: 1.5rem;
    margin-bottom: 1.5rem;
}

.testimonial-text {
    font-size: 0.8438rem;
    font-style: italic;
    margin-bottom: 2rem;
    color: var(--color-text-dark);
}

.author {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.author-img {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: #ccc;
}

.author-info h4 {
    margin-bottom: 0;
    font-size: 0.75rem;
}

.author-info p {
    margin-bottom: 0;
    font-size: 0.6875rem;
}

/* 10. Sustainability */
.sustainability-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.leaf-icon {
    font-size: 1.75rem;
    /* The leaf had gone invisible. It was lime on teal; --color-accent and
       --color-primary now both alias --brand, so it was drawing the glyph in
       the exact colour of the disc behind it. The label on a brand fill is
       --brand-contrast, same as every button. */
    color: var(--brand-contrast);
    margin-bottom: var(--space-4);
    background: var(--brand);
    width: 64px;
    height: 64px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
    box-shadow: var(--shadow-2);
}

.sus-title {
    font-size: 1.875rem;
    color: var(--color-primary);
    margin-bottom: 1rem;
}

.sus-subtitle{
    font-size: 1.125rem;
    color: var(--color-primary);
    margin-bottom: .5rem;
}

.sus-desc {
    font-size: 0.75rem;
    max-width: 600px;
}

/* 11. FAQ Section */
.faq-container {
    max-width: 800px;
    margin: 0 auto;
}

.faq-item {
    border-bottom: 1px solid var(--color-border);
    padding: 1.5rem 0;
    cursor: pointer;
}

.faq-question {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
    font-size: 0.8438rem;
    color: var(--color-text-dark);
}

.faq-icon {
    transition: var(--transition);
}

.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
    padding-top: 0;
    color: var(--color-text-muted);
}

.faq-item.active .faq-answer {
    max-height: 200px;
    padding-top: 1rem;
}

.faq-item.active .faq-icon {
    transform: rotate(180deg);
    color: var(--color-primary);
}

/* Book-a-demo invitation. A real panel rather than the dashed "embed your
   scheduler here" box that used to sit here — a dashed placeholder on a live
   page reads as a site still under construction. */
.demo-invite {
    max-width: 40rem;
    margin: 0 auto;
    padding: var(--space-8) var(--card-padding);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    background: var(--surface);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}

.demo-invite i {
    font-size: 1.25rem;
    color: var(--brand);
}

.demo-invite p {
    margin: 0;
    max-width: 30rem;
}

/* 12. Final CTA
   Was background-color: var(--color-text-dark) with white text on it. That
   token aliases --ink, which in dark is #F2F4F7 — a near-white band carrying
   white text. Same failure as about.html's closing panel: an inverted block
   cannot be built from the ink colour once the ink follows the theme. */
.final-cta {
    background-color: var(--brand-panel);
    color: var(--brand-panel-ink);
    padding: var(--space-9) 0;
    text-align: center;
}

.final-cta h2 {
    color: var(--brand-panel-ink);
    margin-bottom: var(--space-5);
    font-size: clamp(1.5rem, 3vw, 2.625rem);
}

.final-cta p {
    color: color-mix(in srgb, var(--brand-panel-ink) 82%, transparent);
}

.final-cta .btn-outline {
    border-color: color-mix(in srgb, var(--brand-panel-ink) 34%, transparent);
    color: var(--brand-panel-ink);
}

.final-cta .btn-outline:hover {
    background: var(--brand-panel-ink);
    color: var(--brand-panel);
}

/* 13. Footer */
.footer {
    background-color: var(--color-bg-light);
    padding: 4rem 0 2rem;
    border-top: 1px solid var(--color-border);
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 3rem;
    margin-bottom: 3rem;
}

.footer-logo {
    margin-bottom: 1.5rem;
}

.footer-links h4 {
    font-size: 0.8438rem;
    margin-bottom: 1.5rem;
}

.footer-links ul li {
    margin-bottom: 0.75rem;
}

.footer-links ul a {
    color: var(--color-text-muted);
    transition: var(--transition);
}

.footer-links ul a:hover {
    color: var(--color-primary);
}

.social-links {
    display: flex;
    gap: 1rem;
    margin-top: 1.5rem;
}

.social-links a {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--surface);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-primary);
    box-shadow: var(--shadow-sm);
    transition: var(--transition);
}

.social-links a:hover {
    background: var(--color-primary);
    color: var(--brand-contrast);
    transform: translateY(-3px);
}

.footer-bottom {
    text-align: center;
    padding-top: 2rem;
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.6875rem;
}

/* Responsive Adjustments */
@media (max-width: 768px) {
    .nav {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--surface);
        padding: 1.5rem 2rem;
        border-bottom: 1px solid var(--color-border);
        box-shadow: var(--shadow-sm);
        display: none;
    }

    .nav.active {
        display: block;
    }

    .nav ul {
        display: flex;
        flex-direction: column;
        gap: 1.5rem;
    }

    .header-cta {
        display: none;
    }

    .menu-toggle {
        /* flex, not block: the rule above centres the glyph in a 44px target
           with align-items/justify-content, which do nothing on a block. */
        display: flex;
    }

    .hero-container {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .hero-content .subtext {
        margin: 0 auto 2.5rem;
    }

    .hero-actions {
        justify-content: center;
    }

    /* .hero-container centres its text here, but .trust-line is a flex row
       spanning the full column — so the tick stayed hard left while its label
       centred itself, leaving the two visibly unrelated. */
    .trust-line {
        justify-content: center;
        text-align: left;
    }

    /* Two devices side by side at 390px would be two small objects. The sender
       shrinks a little; the receiver shrinks more and tucks further behind, so
       the card stays the thing you actually see. */
    /* Proportions carry the layout now; only the overall cap changes so the
       scene does not dominate a phone screen. */
    .tap-scene {
        max-width: 19rem;
    }

    .problem-grid,
    .features-grid,
    .footer-grid {
        grid-template-columns: 1fr;
    }

}

/* ---------- Template gallery (Product Showcase) ----------
   Cards differ in height by design, so this uses CSS columns rather than a
   grid: rows stay tidy without cropping anyone's layout to a fixed ratio. */
/* Each template is shown inside a phone, because that is the only place anyone
   ever sees one. A masonry column of bare screenshots at four-up read as a
   moodboard of jpegs; in a handset the same image reads as the product.

   A real grid rather than column-count: masonry ordered the cards down each
   column, so the reading order did not match the DOM — bad for a keyboard or a
   screen reader, and confusing to scan. Equal-height frames make a grid
   possible, and the phones are smaller so more fit without shouting. */
/* Fixed counts rather than auto-fill: there are exactly eight templates, and
   auto-fill gave six across with a ragged row of two under it. 4x2 and 2x4
   both come out square. */
.template-gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-6) var(--space-5);
    margin-top: var(--space-7);
    justify-items: center;
    /* Handsets vary in height now that each screen follows its card, so stand
       them on a common baseline: bottoms and captions line up and the tops are
       what varies, which reads as devices set down on a surface. Aligning the
       tops instead leaves the captions at eight different heights. */
    align-items: end;
    /* The stagger below is a transform, which takes no layout space, so the
       dropped column would otherwise hang into the next section and collide
       with its heading. This reserves exactly the offset. */
    padding-bottom: 1.35rem;
}

@media (min-width: 40rem) {
    .template-gallery {
        grid-template-columns: repeat(4, 1fr);
    }
}

.template-gallery figure {
    margin: 0;
    width: 100%;
    max-width: 11rem;
    transition: transform 0.35s cubic-bezier(0.22, 0.9, 0.3, 1);
}

/* Every second device sits lower, so the row reads as an arrangement rather
   than a ruler line of identical objects. Two rows of four then interlock
   instead of forming a grid of boxes. */
.template-gallery figure:nth-child(even) {
    transform: translateY(1.35rem);
}

@media (prefers-reduced-motion: reduce) {
    .template-gallery figure {
        transition: none;
    }
}

/* The handset. A dark bezel, a lit screen and a soft shadow underneath — the
   whole skin is one element plus a ::before for the speaker slot, so it costs
   no extra markup. */
.template-gallery .phone {
    position: relative;
    /* The screen sizes itself from the card, so the clamp below needs the
       handset's own inline size to measure against. */
    container-type: inline-size;
    border-radius: 1.15rem;
    padding: 0.42rem 0.34rem;
    background: linear-gradient(160deg, #2A2F37 0%, #14171C 46%, #23272E 100%);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.55),
        inset 0 0 0 1px rgba(255, 255, 255, 0.10),
        var(--shadow-3);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

/* Earpiece slot. Sits over the top of the screen, centred. */
.template-gallery .phone::before {
    content: '';
    position: absolute;
    top: 0.72rem;
    left: 50%;
    transform: translateX(-50%);
    width: 1.6rem;
    height: 0.16rem;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, 0.22);
    z-index: 2;
}

/* A single diagonal light sweep across the glass. This is the thing that makes
   a mockup read as a physical object rather than a screenshot with a border —
   real screens catch the light, and without it the frame is just a rectangle
   drawn around a jpeg. Kept low-contrast so it never fights the card design
   underneath. */
.template-gallery .phone::after {
    content: '';
    position: absolute;
    inset: 0.42rem 0.34rem;
    border-radius: 0.82rem;
    pointer-events: none;
    z-index: 1;
    background: linear-gradient(122deg,
            rgba(255, 255, 255, 0.20) 0%,
            rgba(255, 255, 255, 0.06) 22%,
            rgba(255, 255, 255, 0) 46%,
            rgba(255, 255, 255, 0) 100%);
    transition: opacity 0.35s ease;
}

:root[data-theme="dark"] .template-gallery .phone::after {
    /* Less of it on a dark page: the same sweep that reads as glass in light
       reads as haze over an already-dim screen. */
    background: linear-gradient(122deg,
            rgba(255, 255, 255, 0.11) 0%,
            rgba(255, 255, 255, 0.03) 24%,
            rgba(255, 255, 255, 0) 48%,
            rgba(255, 255, 255, 0) 100%);
}

.template-gallery img {
    display: block;
    width: 100%;
    /* Every card is shown whole. The screen takes its height from the card, so
       nothing is cropped on either axis and no contact row is cut in half.

       The shaping happens at capture time instead, where there is real material
       to work with: a card squarer than a phone gets more of the page it sits
       on rather than having its sides shaved off (SHOT_MIN_RATIO in
       tools/screenshots/capture.js). That is why the floor below is not doing
       any work today — every shot arrives above it.

       The clamps stay as guards. Left completely free the heights ran 1.48 to
       2.44 and the row read as masonry; if a future template lands outside the
       band, these keep it from dragging the row apart on its own. Raise the
       capture floor before raising this one — filling the frame with backdrop
       is only invisible on templates whose page and card are the same colour,
       and reads as dead space on the rest.

       Container units, not rem, so the band tracks the column at every
       breakpoint and a recapture needs no matching edit here. */
    height: auto;
    min-height: 185cqw;
    max-height: 250cqw;
    object-fit: cover;
    object-position: top center;
    border-radius: 0.82rem;
    background: var(--surface-sunken);
}

/* Picking one up: it lifts, tips very slightly out of the page, and the glare
   moves with it. Perspective on the figure so the tilt is a rotation in space
   rather than a squash. */
.template-gallery figure:hover {
    transform: translateY(-0.4rem);
}

.template-gallery figure:nth-child(even):hover {
    transform: translateY(0.95rem);
}

.template-gallery figure:hover .phone {
    transform: perspective(900px) rotateX(3deg) rotateY(-2.5deg) scale(1.02);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.55),
        inset 0 0 0 1px rgba(255, 255, 255, 0.16),
        0 30px 60px rgba(0, 0, 0, 0.32);
}

.template-gallery figure:hover .phone::after {
    opacity: 0.45;
}

@media (prefers-reduced-motion: reduce) {

    .template-gallery figure:hover .phone,
    .template-gallery figure:hover,
    .template-gallery figure:nth-child(even):hover {
        transform: none;
    }
}

.template-gallery figcaption {
    margin-top: var(--space-3);
    font-size: 0.6875rem;
    line-height: 1.4;
    color: var(--color-text-muted);
    text-align: center;
}

.gallery-note {
    max-width: 680px;
    margin: 0 auto;
    text-align: center;
    color: var(--color-text-muted);
}

/* ── Form fields on a phone ────────────────────────────────────────────────
   iOS Safari zooms the whole page in when a field smaller than 16px takes
   focus, and does not zoom back out when it loses focus. The site's type scale
   puts fields at 12px, which is right on a pointer device and means every tap
   on a phone jerks the layout sideways.

   Raised only under the mobile breakpoint, so the desktop scale is untouched.
   !important because the fields this has to reach are styled inline — the ROI
   calculator's inputs on the homepage carry their size in a style attribute,
   which nothing in a stylesheet can outrank otherwise.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 48rem) {

    input,
    select,
    textarea {
        font-size: 16px !important;
    }
}

/* ── Touch targets ────────────────────────────────────────────────────────
   Measured at 375px: twenty controls sat between 24 and 44px — the mobile nav
   links at 35px tall, the theme toggle and social icons at 40x40, the pill
   buttons at 41, and the form fields at 39-40. All clear the 24px AA floor of
   WCAG 2.5.8, so this is 2.5.5 at AAA, and it only matters to a finger.

   pointer: coarse, so a desktop mouse keeps the current scale — the 40px social
   icons above are a deliberate size and there is no reason to inflate them for
   someone using a cursor.

   min-height rather than height throughout: these elements size to their
   content and padding, and a fixed height would clip the ones that wrap. */
@media (pointer: coarse), (max-width: 48rem) {

    .theme-toggle,
    .social-links a {
        min-width: 44px;
        min-height: 44px;
    }

    .btn,
    button,
    input:not([type="checkbox"]):not([type="radio"]),
    select,
    textarea {
        min-height: 44px;
    }

    /* The nav links are 35px of text with no padding to grow into. inline-flex
       keeps them on their current line while letting min-height apply, which a
       plain inline element ignores. */
    .nav-links a,
    .mobile-menu a,
    nav a,
    /* Footer column links: a nav list, not prose, so the inline exception in
       2.5.8 does not cover them. They are 35px of inline-block text. */
    .footer-col a {
        min-height: 44px;
        min-width: 44px;
        display: inline-flex;
        align-items: center;
    }
}
