/* Intelligena company site — self-hosted, no CDN, CSP-tight. */

:root {
    /* Warm palette, 2026-08-20. This was a deep-navy defence-consultancy site; it is
       a friendly product company's site now, and the colour is most of what carries
       that before anybody reads a word.

       Every pair below was checked for contrast rather than picked by eye:
         --brand on --paper            5.7:1   (link text, AA at any size)
         #fff on --brand               5.7:1   (primary button label)
         --ink-soft on --paper         8.4:1
         --ink-mute on --paper         4.8:1   (AA, and never used below 15px)
         --accent on --dark            6.9:1   (stat values, hero eyebrow)
       A site that sells usability does not get to ship a 3:1 body colour. */
    --ink:        #241b14;
    --ink-soft:   #55463c;
    --ink-mute:   #6f5d50;
    --paper:      #fffdfa;
    --paper-alt:  #fdf3e9;
    --line:       #ecdccb;
    --brand:      #bd3d10;
    --brand-dk:   #93300c;
    --brand-lt:   #fdeade;
    --accent:     #2bb3a3;
    /* The mark carries its own two colours rather than borrowing --brand: the lockup
       is deliberately not the same colour as every link and button on the page, and
       it survived the rebrand unchanged — the palette moved, the identity did not. */
    --mark-triangle: #8b1a1a;
    --mark-eye:      #10265e;
    --dark:       #2b1d14;
    --dark-soft:  #3d2b1e;
    --danger:     #b3261e;
    --danger-bg:  #fdecea;
    --ok:         #10714f;
    --ok-bg:      #e6f6ef;
    /* Rounder than the 14px this replaced. Friendliness is largely radius and
       whitespace; it is not an extra colour. */
    --radius:     20px;
    --radius-sm:  12px;
    --shadow:     0 2px 6px rgba(70,42,20,.05), 0 14px 34px rgba(70,42,20,.09);
    --wrap:       1180px;
    --font:       system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.62;
    color: var(--ink);
    background: var(--paper);
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 { line-height: 1.2; margin: 0 0 .5em; letter-spacing: -.015em; }
h2 { font-size: 2rem; }
h3 { font-size: 1.2rem; }
p { margin: 0 0 1rem; }
a { color: var(--brand); }

.container { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--brand); color: #fff; padding: 12px 20px;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

/* --- Header ---------------------------------------------------------- */
.site-header {
    position: sticky; top: 0; z-index: 50;
    background: rgba(255,255,255,.94);
    backdrop-filter: saturate(160%) blur(8px);
    border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; gap: 24px; min-height: 68px; }
.brand, .brand-lockup { display: flex; align-items: center; gap: 6px; text-decoration: none; color: var(--ink); }

/* The mark: an eye inside a triangle. Sized in `em` so it tracks the wordmark
   rather than needing a second edit whenever the lockup is rescaled. */
.brand-mark { width: 1.62em; height: 1.62em; flex-shrink: 0; overflow: visible; }
.brand-mark-triangle {
    fill: none; stroke: var(--mark-triangle); stroke-width: 2.4;
    stroke-linejoin: round;
}
/* Outline and pupil are one eye and take one colour — a navy ring around a
   differently-coloured dot reads as two shapes, not as an eye. */
.brand-mark-eye { fill: none; stroke: var(--mark-eye); stroke-width: 2; stroke-linejoin: round; }
.brand-mark-pupil { fill: var(--mark-eye); }

.brand-name { font-weight: 700; font-size: 1.45rem; letter-spacing: -.025em; }
.site-nav { display: flex; gap: 18px; margin-left: auto; flex-wrap: wrap; }
.site-nav a {
    text-decoration: none; color: var(--ink-soft); font-weight: 500; font-size: .93rem;
    padding: 6px 0; border-bottom: 2px solid transparent;
}
.site-nav a:hover { color: var(--ink); }
.site-nav a.is-active { color: var(--brand); border-bottom-color: var(--brand); }

/* --- Buttons --------------------------------------------------------- */
.btn {
    display: inline-block; padding: 12px 22px; border-radius: 999px;
    font-weight: 600; font-size: .97rem; text-decoration: none; cursor: pointer;
    border: 1.5px solid transparent; transition: background .15s, color .15s, border-color .15s;
}
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dk); }
.btn-ghost { border-color: currentColor; color: inherit; background: transparent; }
.btn-ghost:hover { background: rgba(255,255,255,.12); }
.btn-sm { padding: 8px 16px; font-size: .9rem; }
.btn-lg { padding: 15px 30px; font-size: 1.03rem; }
.hero .btn-ghost { color: #fff; }

/* --- Hero (one large hero per page) ---------------------------------- */
.hero {
    background-color: var(--dark);
    background-size: cover;
    /* Wide enough that `cover` scales the image to the box's WIDTH and crops top and
       bottom, so the horizontal position is doing nothing here and centre is right. */
    background-position: center;
    color: #fff;
    border-bottom: 1px solid rgba(255,255,255,.08);
}
.hero-inner { padding: 104px 24px 96px; max-width: 860px; }
/* Every hero on this site is a photograph of people. The width is constrained on the
   CHILDREN, not on .hero-inner — that element also carries .container, whose
   `margin: 0 auto` would centre a narrowed block and push the text right, straight onto
   the faces it is meant to avoid. */
.hero-photo .hero-eyebrow,
.hero-photo .hero-title,
.hero-photo .hero-subtitle,
.hero-photo .hero-actions { max-width: 520px; }

/* A layered drop shadow used to be what held the headline off the photograph. The
   panel is that mechanism now, at every width, so the shadow is gone rather than left
   sitting under an opaque card — it was removed inside the panel rule anyway, and
   CSS nothing can ever render is worse than none.

   The eyebrow's colour is NOT part of that. Small tracked-out teal over a daylit
   window is unreadable, and it stays white on any photograph hero — the accent
   remains the accent everywhere else on the site. */
.hero-photo .hero-eyebrow { color: #fff; font-weight: 800; letter-spacing: .16em; }
.hero-eyebrow {
    text-transform: uppercase; letter-spacing: .14em; font-size: .76rem;
    font-weight: 700; color: var(--accent); margin-bottom: 18px;
}
.hero-title { font-size: clamp(2.2rem, 5vw, 3.6rem); margin-bottom: 20px; }
.hero-subtitle { font-size: clamp(1.05rem, 2vw, 1.28rem); color: rgba(255,255,255,.86); max-width: 62ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }

/* --- The landing hero's copy panel ------------------------------------
   The derby photograph is the one hero whose SUBJECT reaches into the headline
   column, and no amount of prompt revision moved it: six faces around a round table
   is a composition that fills the frame. Six seeds across three prompt revisions
   produced five people, five people, five people and then six with the group still
   spanning the whole width.

   So this hero does not rely on a gradient to carry its type. The copy sits on its
   own translucent panel, which makes contrast a property of the PANEL rather than of
   whatever happens to be behind it — the only way to put a headline over a picture
   of people's faces and still be able to state a contrast ratio.

   `backdrop-filter` is an enhancement on top of an already-opaque-enough background,
   never the thing doing the work: Firefox shipped it late and a user agent that
   ignores it must still get a legible headline, not a grey wash.

   The panel drops away below 900px, where the hero is narrow enough that the copy
   spans the full width anyway and a card inset inside a card reads as a mistake. */
/* `.hero-inner` is capped at 860px and also carries `.container`, whose
   `margin: 0 auto` then centres it — so a panel inside it lands in the MIDDLE of a
   1440px page rather than on the page's left gutter, over the very faces it was put
   there to avoid. The panel variant lifts the cap and lets .container's own max-width
   position it, which is what aligns it with every band below. This is the same trap
   the `.hero-photo` comment describes, one level further out. */
.hero-panel .hero-inner { max-width: var(--wrap); padding-top: 88px; padding-bottom: 84px; }
.hero-panel .hero-panel-body,
.hero-panel .hero-dots { max-width: 560px; }
/* Painted at EVERY width. It was gated to >=900px on the assumption that a narrow
   hero is narrow enough for the copy to sit on the picture with a drop shadow — and
   the phone shot settled that: white subtitle over a white tablecloth and six
   sunlit hats, held by a shadow alone and genuinely hard to read. Mobile is where
   most people meet this page, so it is the last place to make contrast conditional. */
.hero-panel .hero-panel-body {
    background: rgba(43,29,20,.72);
    backdrop-filter: saturate(140%) blur(10px);
    border: 1px solid rgba(255,255,255,.14);
    border-radius: var(--radius);
    padding: 26px 24px 24px;
}
@media (min-width: 901px) {
    .hero-panel .hero-panel-body { padding: 34px 36px 32px; }
}
/* The actions sit inside the panel, so their top margin is the gap between the
   subtitle and the button rather than a gap outside the card. */
.hero-panel .hero-actions { margin-top: 26px; }
.hero-panel .hero-subtitle { max-width: 46ch; }

/* --- Home hero rotator ------------------------------------------------
   Slide 0 is the SECTION's own background-image, so there are only n-1 layers and
   returning to the first slide means every layer is off. That is what makes the whole
   thing degrade: with no JavaScript the section still paints slide 0 under the first
   copy panel, and nothing here is required for that to be a correct hero. */
.hero-rotator { position: relative; overflow: hidden; }
.hero-layers { position: absolute; inset: 0; }
.hero-layer {
    position: absolute; inset: 0;
    background-size: cover; background-position: center;
    opacity: 0; transition: opacity .9s ease-in-out;
}
/* The layers must crop the SAME WAY the section does. Slide 0 is the section's own
   background and slides 1..n are these, so a narrow-width rule that moved one and not
   the other would show the first slide following the subject and every later slide
   still centred on empty backdrop — a rotator that appears to drift. No page renders
   layers today; this is here because the mechanism is deliberately kept alive
   (see test_hero_rotator) and a half-applied rule is how it would come back broken. */
@media (max-width: 1100px) {
    .hero-layer { background-position: 68% center; }
}
.hero-layer.is-active { opacity: 1; }
/* The copy has to sit above the layers, and .hero-inner is the only positioned
   ancestor it can take a stacking context from. */
.hero-rotator .hero-inner { position: relative; z-index: 1; }

/* Grid-stacked, not absolutely positioned: every panel occupies the same cell, so the
   TALLEST one sets the hero's height once. Absolute positioning would collapse the
   height to the actions block and make the page jump on every slide change. */
.hero-copies { display: grid; }
.hero-copy {
    grid-area: 1 / 1;
    opacity: 0; visibility: hidden;
    transition: opacity .55s ease-in-out, visibility 0s linear .55s;
}
.hero-copy.is-active {
    opacity: 1; visibility: visible;
    transition: opacity .55s ease-in-out, visibility 0s;
}

.hero-dots { display: flex; gap: 10px; margin-top: 34px; flex-wrap: wrap; }
.hero-dot {
    width: 34px; height: 5px; padding: 0; border: 0; border-radius: 999px;
    background: rgba(255,255,255,.55);
    cursor: pointer; transition: background .25s ease, transform .25s ease;
    /* A 5px-tall control is far under the 24px minimum target size, so the hit area is
       extended with padding the eye never sees. */
    box-sizing: content-box;
    border-top: 10px solid transparent; border-bottom: 10px solid transparent;
    background-clip: content-box;
}
.hero-dot:hover { background: rgba(255,255,255,.62); background-clip: content-box; }
/* Outside the panel and directly on the photograph, so a 5px bar at 34% alpha over
   sunlit grass is invisible. The shadow is what makes it a control you can see. */
.hero-dot { box-shadow: 0 1px 6px rgba(31,22,16,.55); }
.hero-dot.is-active { background: var(--accent); background-clip: content-box; }
.hero-dot:focus-visible {
    outline: 2px solid #fff; outline-offset: 3px;
}

/* An auto-advancing hero is precisely what this preference is about. The timer is
   stopped in hero.js as well — stripping the transition alone would still move the
   content, just abruptly. */
@media (prefers-reduced-motion: reduce) {
    .hero-layer,
    .hero-copy { transition: none; }
}

/* --- Bands ----------------------------------------------------------- */
.band { padding: 76px 0; }
.band-alt { background: var(--paper-alt); }
.band-intro { padding: 56px 0 12px; }
.band-dark { background: var(--dark); color: rgba(255,255,255,.86); }
.band-dark h2, .band-dark h3 { color: #fff; }
.lede { font-size: 1.24rem; line-height: 1.6; color: var(--ink-soft); max-width: 68ch; }
.lede-sm { font-size: 1.08rem; color: var(--ink-soft); font-weight: 500; }
.section-title { font-size: clamp(1.7rem, 3vw, 2.3rem); }
.section-sub { color: var(--ink-mute); max-width: 62ch; margin-bottom: 36px; }
.band-dark .section-sub { color: rgba(255,255,255,.68); }
.mini-title { font-size: .82rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-mute); margin-top: 22px; }
.footnote-inline { color: var(--ink-mute); font-size: .95rem; margin-top: 24px; max-width: 66ch; }

.ticks { list-style: none; padding: 0; margin: 14px 0 0; }
.ticks li { position: relative; padding-left: 26px; margin-bottom: 9px; font-size: .95rem; color: var(--ink-soft); }
.ticks li::before {
    content: ""; position: absolute; left: 4px; top: .55em;
    width: 9px; height: 9px; border-radius: 50%; background: var(--accent);
}
.band-dark .ticks li { color: rgba(255,255,255,.8); }

/* --- Stats ----------------------------------------------------------- */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 34px; }
.stat-value {
    font-size: 2.8rem; font-weight: 800; color: var(--brand);
    margin: 0 0 8px; letter-spacing: -.02em;
}
.stat-label { color: var(--ink-soft); font-size: .95rem; margin: 0; }
/* On a dark band the same two elements need the other end of the scale. Stated as an
   override rather than as the default, because the light band is now the common case
   and a white-by-default label is invisible exactly where nobody looks. */
.band-dark .stat-value { color: var(--accent); }
.band-dark .stat-label { color: rgba(255,255,255,.78); }

.text-link { font-weight: 600; text-decoration: none; }
.text-link:hover { text-decoration: underline; }

/* --- Landing: the fundamentals --------------------------------------- */
.fundamental-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 22px;
}
.fundamental-card {
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 26px 28px 24px; box-shadow: var(--shadow);
    display: flex; flex-direction: column;
}
.fundamental-card h3 { font-size: 1.12rem; margin-bottom: 10px; }
.fundamental-summary { color: var(--ink-soft); font-size: .97rem; }
/* Pushed to the bottom so the "in our apps" half of every card lines up across the
   row however long the principle above it happens to be. */
.fundamental-practice {
    margin: auto 0 0; padding-top: 16px; border-top: 1px solid var(--line);
    font-size: .92rem; color: var(--ink-soft);
}
.fundamental-tag {
    display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .12em;
    font-weight: 700; color: var(--brand); margin-bottom: 6px;
}

/* --- Landing: the experimentation loop ------------------------------- */
.loop-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 18px; }
.loop-step {
    display: grid; grid-template-columns: 68px minmax(0, 1fr); gap: 22px; align-items: start;
    background: var(--dark-soft); border: 1px solid rgba(255,255,255,.09);
    border-radius: var(--radius); padding: 24px 28px;
}
.loop-number {
    font-size: 2rem; font-weight: 800; color: var(--accent); margin: 0;
    line-height: 1; font-variant-numeric: tabular-nums;
}
/* The card paints its own dark background, so it carries its own foreground.
   Left to inherit, an h3 here is --ink on --dark-soft the moment this component
   is used outside a .band-dark — which the tech page does. */
.loop-step h3 { font-size: 1.08rem; margin-bottom: 6px; color: #fff; }
.loop-step p { margin: 0; color: rgba(255,255,255,.78); font-size: .97rem; }

/* --- Alpha badge ------------------------------------------------------ */
.badge {
    display: inline-block; border-radius: 999px; padding: 5px 14px;
    font-size: .74rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
    margin: 0 0 12px;
}
.badge-alpha { background: var(--brand-lt); color: var(--brand-dk); border: 1px solid #f0c7b0; }

/* --- Landing: product teasers ---------------------------------------- */
.teaser-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 26px;
}
/* The card IS the anchor — see home.html. Everything inside it is inline-level, so
   the block layout has to be restated here rather than inherited from <article>. */
.teaser-card {
    display: block; text-decoration: none; color: inherit;
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    overflow: hidden; box-shadow: var(--shadow);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.teaser-card:hover {
    transform: translateY(-3px); border-color: var(--brand);
    box-shadow: 0 4px 10px rgba(70,42,20,.07), 0 20px 44px rgba(70,42,20,.13);
}
.teaser-image { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--paper-alt); }
.teaser-body { display: block; padding: 22px 26px 26px; }
.teaser-name { display: block; font-size: 1.35rem; font-weight: 700; line-height: 1.2; margin-bottom: 4px; }
.teaser-tagline { display: block; color: var(--ink-soft); }
.teaser-more { display: block; margin-top: 14px; font-weight: 600; color: var(--brand); }
.teaser-card:hover .teaser-more { text-decoration: underline; }
.band-action { margin: 38px 0 0; }

/* --- A soft band ------------------------------------------------------ */
.band-soft { background: var(--paper-alt); }

/* --- Company: about paragraph + team grid ------------------------------ */
.about-copy { font-size: 1.08rem; line-height: 1.7; color: var(--ink-soft); max-width: 74ch; }

/* Not an anchor grid like .teaser-card — nobody clicks a person, so it is a
   plain <li> list rather than a list of links. */
.team-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: 30px; list-style: none; padding: 0; margin: 0;
}
.team-card { text-align: center; }
.team-photo {
    width: 132px; height: 132px; border-radius: 50%; object-fit: cover;
    background: var(--paper); border: 1px solid var(--line); box-shadow: var(--shadow);
    margin: 0 auto 14px;
}
.team-name { font-weight: 700; font-size: 1.05rem; margin: 0; }
.team-role { color: var(--ink-mute); margin: 2px 0 0; }
.team-note { color: var(--ink-soft); font-size: .92rem; margin: 8px 0 0; max-width: 24ch; margin-left: auto; margin-right: auto; }

/* --- Launch: the product bands ---------------------------------------- */
.product-layout {
    display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
    gap: 56px; align-items: center;
}
/* Alternating rows, so the page does not read as two identical blocks. Done with
   `order` on the FIGURE, so the DOM order — name before picture — stays the reading
   order in every case; and driven by a class the TEMPLATE assigns, because
   `:nth-of-type` here counts every <section> on the page rather than the products. */
.product-band-mirrored .product-figure { order: 2; }
.product-figure img {
    width: 100%; border-radius: var(--radius); box-shadow: var(--shadow);
    background: var(--paper-alt);
}
/* The header is sticky at 68px, and `html { scroll-behavior: smooth }` means a jump
   to #int_lms from the landing page's teaser card parks the product's name UNDER it —
   the page moves, the thing you asked for is hidden, and it reads as a link that went
   to the wrong place. */
.product-band { scroll-margin-top: 88px; }
.product-name { font-size: clamp(1.8rem, 3.4vw, 2.5rem); margin-bottom: 6px; }
.product-tagline { font-size: 1.2rem; color: var(--ink); font-weight: 600; margin-bottom: 14px; }
.product-who { color: var(--ink-mute); font-size: .95rem; }
.product-cta { margin: 26px 0 0; }

/* --- The dotted terms list: /products/ (dark) and /tech/ (light) ------- */
/* Authored white for the alpha terms on /products/, which is a .band-dark. The tech
   page renders the same component inside .band-soft — white on --paper-alt is 1.05:1,
   so the copy was invisible and only the accent dots showed. Same shape as .ticks
   below: a light default, and the dark band overrides it. Exactly the mistake
   .loop-step's comment above already describes, pointing the other way. */
.terms-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; max-width: 74ch; }
.terms-list li {
    position: relative; padding-left: 30px;
    color: var(--ink-soft); font-size: 1.02rem;
}
.band-dark .terms-list li { color: rgba(255,255,255,.82); }
.terms-list li::before {
    content: ""; position: absolute; left: 0; top: .5em;
    width: 12px; height: 12px; border-radius: 50%; background: var(--accent);
}

/* --- Contact: the aside ------------------------------------------------ */
.reason-list { list-style: none; padding: 0; margin: 0 0 10px; }
.reason-list li { padding: 16px 0; border-bottom: 1px solid var(--line); }
.reason-list li:last-child { border-bottom: 0; }
.reason-list h3 { font-size: 1rem; margin-bottom: 4px; }
.reason-list p { font-size: .93rem; color: var(--ink-soft); margin: 0; }
.confirmation-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }

/* --- CTA ------------------------------------------------------------- */
.band-cta { background: linear-gradient(120deg, var(--brand-dk) 0%, var(--brand) 62%, #e0682f 100%); color: #fff; }
.cta-inner { display: flex; align-items: center; justify-content: space-between; gap: 30px; flex-wrap: wrap; }
.cta-inner h2 { margin-bottom: 6px; }
.cta-inner p { margin: 0; color: rgba(255,255,255,.86); }
.band-cta .btn-primary { background: #fff; color: var(--brand-dk); }
.band-cta .btn-primary:hover { background: var(--brand-lt); }

/* --- Partner form ---------------------------------------------------- */
.partner-layout { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .85fr); gap: 60px; align-items: start; }
.form-title { font-size: 1.7rem; }
.form-intro { color: var(--ink-mute); margin-bottom: 26px; }
.partner-form .field { margin-bottom: 20px; }
.partner-form label { display: block; font-weight: 600; font-size: .93rem; margin-bottom: 7px; }
.req { color: var(--danger); margin-left: 3px; }
.partner-form input[type="text"],
.partner-form input[type="email"],
.partner-form select,
.partner-form textarea {
    width: 100%; padding: 12px 14px; font: inherit; font-size: .98rem; color: var(--ink);
    background: var(--paper); border: 1.5px solid var(--line); border-radius: var(--radius-sm);
}
.partner-form textarea { resize: vertical; min-height: 140px; }
.partner-form input:focus, .partner-form select:focus, .partner-form textarea:focus {
    border-color: var(--brand); outline: 3px solid rgba(31,79,216,.16); outline-offset: 0;
}
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--danger); background: var(--danger-bg); }
.field-help { font-size: .85rem; color: var(--ink-mute); margin: 6px 0 0; }
.field-error { font-size: .88rem; color: var(--danger); font-weight: 600; margin: 7px 0 0; }
.form-error {
    background: var(--danger-bg); border: 1px solid #f3c2bd; border-left: 5px solid var(--danger);
    color: #7d1c16; border-radius: var(--radius-sm); padding: 16px 20px; margin-bottom: 26px;
}
.form-actions { margin-top: 30px; }
.form-note { font-size: .87rem; color: var(--ink-mute); margin: 12px 0 0; }
/* Honeypot. `display:none` (not off-screen positioning) so the field is out of the
   visual tree, the a11y tree AND the tab order — an off-screen input is still
   "visible" to assistive tech and to a keyboard user. Hidden inputs are still
   submitted, which is the whole point; it is never `required`, so it cannot block
   a submit. */
.hp-wrap { display: none; }

.confirmation {
    background: var(--ok-bg); border: 1px solid #b9e3d0; border-left: 5px solid var(--ok);
    border-radius: var(--radius); padding: 34px 36px;
}
.confirmation h2 { color: var(--ok); font-size: 1.5rem; }

.partner-aside { background: var(--paper-alt); border: 1px solid var(--line); border-radius: var(--radius); padding: 30px 32px; }
.aside-title { font-size: 1.12rem; margin-top: 26px; }
.aside-title:first-child { margin-top: 0; }
.engagement-list { list-style: none; padding: 0; margin: 0 0 10px; }
.engagement-list li { padding: 16px 0; border-bottom: 1px solid var(--line); }
.engagement-list li:last-child { border-bottom: 0; }
.engagement-list h3 { font-size: 1rem; margin-bottom: 2px; }
.engagement-duration { font-size: .82rem; text-transform: uppercase; letter-spacing: .08em; color: var(--accent); font-weight: 700; margin-bottom: 8px; }
.engagement-list p { font-size: .93rem; color: var(--ink-soft); margin: 0; }

/* Reach-us-directly block on /contact/ — outside <noscript> on purpose, so the
   entity, address and phone are readable even when the form itself cannot run. */
.contact-identity { font-style: normal; font-size: .93rem; line-height: 1.6; color: var(--ink-soft); margin: 14px 0 10px; }
.contact-identity strong { color: var(--ink); }
.contact-direct { list-style: none; padding: 0; margin: 0; font-size: .95rem; }
.contact-direct li { margin-bottom: 6px; }

/* --- Footer ---------------------------------------------------------- */
.site-footer { background: var(--dark); color: rgba(255,255,255,.7); padding: 56px 0 30px; margin-top: 0; }
.footer-inner { display: flex; justify-content: space-between; gap: 34px; flex-wrap: wrap; padding-bottom: 26px; border-bottom: 1px solid rgba(255,255,255,.1); }
.footer-brand .brand-name { color: #fff; font-size: 1.45rem; }
/* Both mark colours are dark by design and neither survives --dark: the whole mark
   goes white here so the lockup reads at speed. (Before the recolour the eye kept
   its --accent teal; a navy eye on near-black is simply not visible.) */
.footer-brand .brand-mark-triangle { stroke: #fff; }
.footer-brand .brand-mark-eye { stroke: #fff; }
.footer-brand .brand-mark-pupil { fill: #fff; }
.footer-brand p { margin: 6px 0 0; font-size: .95rem; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 20px; align-items: center; }
.footer-nav a { color: rgba(255,255,255,.78); text-decoration: none; font-size: .94rem; }
.footer-nav a:hover { color: #fff; text-decoration: underline; }
.footer-legal { padding-top: 22px; }
.footer-legal p { font-size: .82rem; color: rgba(255,255,255,.5); margin: 0 0 6px; max-width: 90ch; }
/* The legal row had NO rule of its own and fell through to `a { color: var(--brand) }`
   — a link colour chosen for white paper, rendered on the near-black footer. It was
   already under 3:1 with the old blue and the warm palette only made it visible; a
   colour that is wrong on both palettes was never a palette problem. */
.footer-legal-links { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 12px; }
.footer-legal-links a { color: rgba(255,255,255,.86); text-decoration: none; font-size: .88rem; }
.footer-legal-links a:hover { color: #fff; text-decoration: underline; }
/* The SAME defect, on the same ground, missed when the rule above was written: the
   telephone and the support address inside the shared identity block are links too,
   also had no rule of their own, and were also still inheriting the paper link colour —
   measured in the browser at 2.98:1 against a 4.5 floor. A fix aimed at the selector
   somebody was looking at rather than at every link on that background. The shared
   int_legal block ships no stylesheet of its own, so the colour must come from here. */
.site-footer .int-legal-identity a { color: rgba(255,255,255,.86); text-decoration: underline; }
.site-footer .int-legal-identity a:hover { color: #fff; }

/* The staff console, and the only link in the footer that is not part of the public
   site. Quieter than its neighbours on purpose — it is here so somebody who needs it
   can find it, not to be found by somebody who does not. Quieter, NOT unreadable:
   --ink-mute is a token for warm paper and lands at about 2:1 on this ground. */
.footer-internal { color: rgba(255,255,255,.55) !important; }
.footer-internal:hover { color: #fff !important; }

.env-badge {
    display: inline-block; background: var(--accent); color: var(--dark);
    border-radius: 6px; padding: 3px 12px; font-weight: 700; font-size: .76rem !important;
    letter-spacing: .06em;
}

/* --- The technology summary on the landing page ------------------------
   Two columns: the claim, and three things it cashes out as. The band is NOT a
   link — it holds a list, and a list inside an anchor is one tab stop that a
   screen reader announces as one run-on sentence. The button is the target. */
.band-tech { background: var(--brand-lt); }
.tech-summary {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
    gap: 48px; align-items: start;
}
.section-eyebrow {
    text-transform: uppercase; letter-spacing: .14em; font-size: .76rem;
    font-weight: 700; color: var(--brand-dk); margin: 0 0 14px;
}
.tech-summary-copy p { color: var(--ink-soft); max-width: 56ch; }
/* `.band-action` centres nothing on its own but carries a 38px top margin meant for
   a full-width row under a grid. Inside a column it only needs the margin. */
.band-action-left { margin-top: 26px; }
.tech-summary-points { margin-top: 8px; }
.tech-summary-points li { font-size: 1rem; color: var(--ink); margin-bottom: 16px; }

/* --- The tech page's contrast table -----------------------------------
   A real <table>: it IS tabular — the same four questions answered two ways — and
   a row header announced before each cell is the only way it reads correctly
   without sight of the columns.

   `.table-scroll` is the wrapper, and it is not optional. A three-column table of
   prose cannot narrow past its content, so without its own scroller the PAGE BODY
   scrolls sideways on a phone and every other section goes with it. tabindex makes
   the scroller reachable by keyboard, which is the half of `overflow-x` that is
   usually forgotten — a region you can only scroll by dragging is a region a
   keyboard user cannot read the right-hand side of. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.contrast-table { width: 100%; min-width: 720px; border-collapse: collapse; text-align: left; }
.contrast-table th, .contrast-table td {
    padding: 18px 22px; vertical-align: top;
    border-bottom: 1px solid rgba(255,255,255,.12);
}
.contrast-table thead th {
    font-size: .78rem; text-transform: uppercase; letter-spacing: .12em;
    color: rgba(255,255,255,.62); font-weight: 700; padding-bottom: 10px;
}
.contrast-table tbody th {
    width: 26%; color: #fff; font-weight: 700; font-size: 1rem;
}
.contrast-table td { color: rgba(255,255,255,.7); font-size: .95rem; }
/* Our column is the one being argued for, so it is the one that reads as present
   rather than as a footnote. Weight and a left rule, never colour alone —
   "colour is never the only thing carrying a meaning" is one of the eight. */
.contrast-table .contrast-ours {
    color: #fff; border-left: 2px solid var(--accent); background: rgba(43,179,163,.07);
}
.contrast-table tbody tr:last-child th,
.contrast-table tbody tr:last-child td { border-bottom: 0; }

/* The loop-list number slot carries a product name on the tech page, so it needs to
   be type rather than a numeral: same column, same alignment, readable width. */
.moment-product {
    font-size: 1rem !important; font-weight: 700; color: var(--accent);
    line-height: 1.3; letter-spacing: 0;
}

/* --- Responsive ------------------------------------------------------ */
@media (max-width: 900px) {
    .partner-layout, .product-layout, .tech-summary { grid-template-columns: 1fr; gap: 32px; }
    /* Reset the alternation with the columns it exists to alternate. */
    .product-band-mirrored .product-figure { order: 0; }
    .hero-inner { padding: 72px 24px 64px; }
    .band { padding: 56px 0; }
}
/* Below ~1100px the hero is TALLER than the image's aspect, so `cover` flips: it
   scales to the box's HEIGHT and crops horizontally instead. A centred crop then
   shows the middle of the frame — and every hero on this site deliberately puts its
   subject RIGHT of centre, in the half the copy panel does not cover. So the middle
   of the frame is the one part of these photographs with nobody in it, and a phone
   was getting a sliver of empty studio wall behind the panel.

   68% rather than `right`: hard right-alignment crops INTO the subject at the frame
   edge — the group hero's rightmost person and the skydiver's parachute both lose
   their outer edge. 68% was picked by rendering 60/68/75 at 390px and comparing:
   at 60 and 75 the contact portrait is cut through the eyes and the skydiver shows
   canopy instead of a face, while the group stays legible at all three.

   Measured, not assumed: 1100px is where the hero box (656px tall) passes the 1.78:1
   of a 16:9 hero, and it is below the 1100px width at which the copy panel stops
   being a half-width column. */
@media (max-width: 1100px) {
    .hero { background-position: 68% center; }
}

@media (max-width: 680px) {
    .header-inner { flex-wrap: wrap; min-height: 0; padding-top: 12px; padding-bottom: 12px; }
    .site-nav { order: 3; width: 100%; margin-left: 0; gap: 16px; }
    .loop-step { grid-template-columns: 1fr; gap: 6px; }
    .cta-inner { flex-direction: column; align-items: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { transition: none !important; }
}

/* --- Work-email verification (partner form) ---------------------------
   Rendered by the server and shown/hidden by marketing/partner-verify.js. The
   [hidden] rules are explicit because `.verify-row { display: flex }` would
   otherwise beat the attribute's own UA rule and show a row that is meant to be
   gone — the classic "hidden element still on screen" flex bug. */
.verify-block { margin-top: 10px; }
.verify-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.verify-block [hidden] { display: none !important; }

.btn-outline {
    background: transparent; color: var(--brand); border-color: var(--brand);
}
.btn-outline:hover:not(:disabled) { background: var(--brand-lt); }
.partner-form .btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-link {
    background: none; border: 0; padding: 0; font: inherit; font-size: .88rem;
    color: var(--brand); text-decoration: underline; cursor: pointer;
}
.btn-link:disabled { color: var(--ink-mute); text-decoration: none; cursor: not-allowed; }

.verify-badge {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--ok-bg); color: var(--ok); border: 1px solid #b9e3d0;
    border-radius: 999px; padding: 5px 14px; font-size: .88rem; font-weight: 700;
}

.verify-code { margin-top: 12px; }
.verify-code label {
    display: block; font-weight: 600; font-size: .88rem; margin-bottom: 6px;
}
/* Narrower than a normal field: a six-character box that spans the form reads as
   somewhere to write a sentence. */
.partner-form .verify-code input[type="text"] {
    width: 9.5em; letter-spacing: .28em; font-variant-numeric: tabular-nums;
    text-align: center;
}

.verify-status { font-size: .88rem; color: var(--ink-mute); margin: 9px 0 0; }
.verify-status:empty { margin: 0; }
.verify-status-error { color: var(--danger); font-weight: 600; }

/* The widget paints its own card; this only keeps it in the form's rhythm. */
.captcha-field altcha-widget { display: block; max-width: 320px; }
