/*
 * CMLE Team — theme
 *
 * Second layer on top of site.css. The hero, the roadmap strip, the form
 * and the footer are taken from there; the palette and the whole section
 * layout are rebuilt here.
 *
 * Palette: neutral dark ground, a single cold-blue accent. The indigo/orange
 * pair is dropped. site.css reads its colours through --indigo / --orange,
 * so the variables are redefined here — the hero, the strip and the footer
 * then follow the new palette automatically.
 */

:root {
    --bg:          #0A0C10;
    --bg-2:        #0E1116;
    --card:        #131820;
    --card-hover:  #1A202A;

    --text:        #EEF1F5;
    --text-2:      #9AA4B2;
    --muted:       #626D7C;

    --indigo:      #3D7BFF;
    --indigo-rgb:  61, 123, 255;
    --indigo-soft: #79A2FF;
    --indigo-deep: #2757CC;

    /* The second colour stays cold too: the accent is meant to be singular,
       the second tone exists only to tell things apart. */
    --orange:      #8CA0BC;
    --orange-rgb:  140, 160, 188;
    --orange-deep: #6B7C96;

    --border:       rgba(var(--accent-rgb), 0.14);
    --border-hover: rgba(var(--accent-rgb), 0.40);

    /* The watermark numeral beside every section heading. One value, so a
       section with its own layout cannot end up with a smaller number than
       the one above it. */
    --section-number-size: clamp(76px, 10vw, 158px);
}

/* ---------- hero height ---------- */

/* site.css gives a fixed padding; here it is tied to the viewport height
   and enlarged a little. Padding instead of min-height: if the content
   grows the hero grows with it, and the text is never clipped on a short
   screen. */
.hero {
    padding: calc(var(--nav-h) + clamp(120px, 17vh, 210px)) 0 clamp(128px, 18vh, 220px);
}

/* The headline is two lines and only two, each one its own block so the
   break is written into the markup rather than left to wherever the column
   happens to run out. site.css holds it to 17ch, which was right for a
   headline that wrapped freely and is far too narrow for a line meant to
   stay whole; the cap is dropped here.

   The size is what keeps each line whole. The longest is nine characters
   and the column it stands in is at its narrowest — around 450px — at
   exactly the width where the hero splits into two columns, so the ceiling
   is set from that rather than from the widest screen.

   Archivo Black is the headline's own face and is used nowhere else on the
   page — the site's display font stays Montserrat for every other heading,
   so the hero is the one thing speaking in a different voice.

   It ships in a single weight, so font-weight stays 400: asking for a bold
   the family does not have gets a synthetic one, and a synthesised bold on
   a face already this heavy smears. Being wide it needs a lower ceiling
   than Montserrat could take, and slightly less negative tracking — the
   letters are close together to begin with. */
.hero h1 {
    max-width: none;
    font-family: 'Archivo Black', var(--display);
    font-size: clamp(2.3rem, 6.6vw, 4.9rem);
    font-weight: 400;
    line-height: 1.06;
    letter-spacing: -0.025em;
}

.hero-line { display: block; }

/* A gradient clips to the text it paints, so the coloured line must be the
   element carrying the gradient rather than a span inside a wider block. */
.hero-line.gradient-text { width: fit-content; }

/* ---------- section skeleton ---------- */

/* Generous spacing and a height that fills the screen. vh instead of a
   fixed pixel value: browser chrome takes up a different amount of space on
   every screen, and centring the section this way is more reliable than a
   fixed number. If the content is long the section grows, it is never
   constrained. */
.block {
    padding: clamp(48px, 6.5vh, 84px) 0;
}

.block > .wrap { width: 100%; }

.block-head {
    max-width: 760px;
    margin: 0 auto clamp(26px, 3.2vh, 40px);
    text-align: center;
}

/* A product's mark standing over its section heading. Larger than the one
   on a component card, because here it is the only mark on the screen
   rather than one of six, and it answers to a heading three times the size
   of a card title.

   alt is empty on purpose: the heading directly under it says the
   collection's name, so giving the image the same name would have a screen
   reader read it twice. It is decoration over a title, not a title. */
.block-mark {
    display: block;
    width: clamp(108px, 13.5vw, 156px);
    height: auto;
    margin: 0 auto 20px;
}

/* The section number is not a label but a watermark in the section's top
   corner, very large and nearly transparent.

   It is a direct child of the <section> rather than of the heading block,
   which is what lets it sit in the corner of the section whatever the
   layout inside is — the origin section puts its heading in a narrow column
   of its own, and a number anchored to that column would land in the middle
   of the page instead of at its edge.

   Being outside .wrap is also what puts it under the text: site.css gives
   .section > .wrap a z-index of 1, so every paragraph on the page paints
   above this. One size for all of them, declared once in :root — a size
   written a second time is a size that drifts.

   The horizontal inset lines the numeral up with the text column: half the
   space left over beside a 1180px wrap, plus the wrap's own 24px padding.
   Below that width there is no space left over and max() holds it at 24px. */
.block-number {
    position: absolute;
    top: clamp(10px, 2.2vh, 30px);
    left: max(24px, calc(50% - var(--wrap) / 2 + 24px));
    z-index: 0;
    font-family: var(--display);
    font-size: var(--section-number-size);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--accent);
    opacity: 0.085;
    pointer-events: none;
    user-select: none;
}

/* Odd sections keep the number on the left, even ones carry this and take
   the right — so reading down the page the numbers alternate corners.
   Written as a class on the element rather than worked out with
   :nth-child, because the sections are not all siblings of one type: the
   hero is a section too and the closing call to action carries no number. */
.block-number.on-right {
    left: auto;
    right: max(24px, calc(50% - var(--wrap) / 2 + 24px));
}

@media (max-width: 1080px) {
    .block-number { display: none; }
}

.block-head h2 {
    position: relative;
    margin: 0 0 20px;
    padding-bottom: 22px;
    font-size: clamp(2.1rem, 4.5vw, 3.35rem);
    line-height: 1.12;
    letter-spacing: -0.028em;
}

/* The rule under a section heading: a hairline fading out at both ends with
   a lit diamond on its middle. Drawn by the heading's own two pseudo-
   elements rather than by a span each section would have to carry, so a
   section written tomorrow gets it by being a section.

   Both are pinned to the heading's bottom edge, which the padding above
   holds clear of the text; the diamond is then pulled half its own height
   down so it centres on the line rather than sitting above it. */
.block-head h2::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 46%;
    max-width: 360px;
    height: 1px;
    transform: translateX(-50%);
    background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.5), transparent);
}

.block-head h2::before {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 0;
    z-index: 1;
    width: 9px;
    height: 9px;
    transform: translate(-50%, 50%) rotate(45deg);
    background: var(--accent);
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.85);
}

.block-head p {
    margin: 0 auto;
    font-size: 17px;
    line-height: 1.75;
    color: var(--text-2);
    max-width: 62ch;
}

/* The roadmap section cannot be a .block: the box carrying the rail sits
   outside .wrap, directly as the section's own child, because the rail
   uses the full width of the screen. .block is flex, so it put the heading
   and the rail side by side in two columns and broke both. Same spacing,
   without changing the flow. */
.strip { padding: clamp(48px, 6.5vh, 84px) 0; }

/* ---------- 01 · corporate ---------- */

/* Three tabs on the left, a photograph on the right. The text side is given
   the larger share: a panel of prose needs a reading measure, while the
   picture only needs to be big enough to read as a picture.

   The photograph sits on the vertical middle of the column beside it. That
   is why the panels below are given a floor height: the three of them are
   not naturally the same length, and a centred picture moves by half of
   whatever they differ by every time somebody changes tab. */
.corporate-split {
    display: grid;
    gap: 36px;
    grid-template-columns: 1fr;
    align-items: center;
}

@media (min-width: 900px) {
    .corporate-split { grid-template-columns: 1.15fr 0.85fr; gap: 56px; }
}

.tab-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: clamp(22px, 2.6vh, 30px);
    border-bottom: 1px solid var(--border);
}

.tab {
    position: relative;
    padding: 11px 20px;
    border: 0;
    background: none;
    font-family: inherit;
    font-size: 15.5px;
    font-weight: 600;
    color: var(--text-2);
    cursor: pointer;
    transition: color 0.2s ease;
}

.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--accent); }

/* The underline sits on the bar's own rule rather than above it, and is
   drawn by a scale rather than by switching a colour, so it slides into
   width instead of appearing all at once. */
.tab::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transition: transform 0.25s ease;
}

.tab[aria-selected="true"]::after { transform: scaleX(1); }

/* A floor height, set close to the tallest panel rather than to the
   shortest: the picture beside these is centred on the column, so any
   difference between panels moves it by half of that difference. Holding
   the three to roughly one height is what keeps the photograph still.

   Only on the wide layout — on a phone the picture is stacked under the
   text, nothing is centred against anything, and the reserved space would
   only be a gap. */
@media (min-width: 900px) {
    .tab-panel { min-height: 400px; }
}

.tab-panel p {
    margin: 0 0 16px;
    font-size: 16.5px;
    line-height: 1.78;
    color: var(--text-2);
}

.tab-panel p:last-child { margin-bottom: 0; }

/* The frame holds its shape with an aspect ratio rather than with whatever
   the file happens to be, so the row does not jump the day the photograph
   is swapped for one of a different size. */
.corporate-photo {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 40px 90px -50px rgba(0, 0, 0, 0.9);
}

.corporate-photo img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    filter: saturate(0.88) brightness(0.86);
}

/* ---------- the "Biz" tab timeline ---------- */

/* The heading sits on top like every other section's, so the three entries
   have the whole column to themselves. */
.origin-entries { width: 100%; }

.origin-entry { position: relative; padding-left: 132px; }
.origin-entry + .origin-entry { margin-top: clamp(26px, 3vh, 36px); }

/* The label sits in the margin with a hairline running from it to the text.
   It is given a fixed width rather than being left to size itself, so the
   hairline starts at the same x on every entry and the three of them line
   up on a common axis — the present-day label is nearly twice the width of
   a year and would otherwise push its own line across into the paragraph. */
.origin-marker {
    position: absolute;
    left: 0;
    top: 9px;
    width: 92px;
    font-family: var(--mono);
    font-size: 13px;
    letter-spacing: 0.14em;
    color: var(--accent);
}

.origin-marker::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 100%;
    width: 26px;
    height: 1px;
    background: linear-gradient(90deg, var(--accent), transparent);
}

.origin-entry p {
    margin: 0;
    font-size: 16.5px;
    line-height: 1.78;
    color: var(--text-2);
}

/* A 132px indent leaves too little room for the paragraph on a phone, so
   the label goes back into the flow above its text and the hairline, which
   has nothing to point at any more, is dropped. */
@media (max-width: 620px) {
    .origin-entry { padding-left: 0; }

    .origin-marker {
        position: static;
        display: block;
        width: auto;
        margin-bottom: 8px;
    }

    .origin-marker::after { display: none; }
}

/* ---------- 03 · ecosystem cards ---------- */

.product-cards {
    display: grid;
    gap: 18px;
    grid-template-columns: 1fr;
}

@media (min-width: 720px)  { .product-cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .product-cards { grid-template-columns: repeat(3, 1fr); } }

.product-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: clamp(24px, 2.6vw, 32px);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--card);
    overflow: hidden;
    transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

/* Always on, not a hover reveal: a lit top edge and a glow behind the logo,
   so a card carries some light before anybody touches it. The same language
   the focus cards further down the page use, which is what makes the two
   grids read as one family rather than two components. */
.product-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

/* Centred horizontally but sunk below the card's foot, so only the top of
   the circle rises into it. Sitting on the card's middle put the brightest
   part of the light directly behind the paragraph and greyed the text out;
   down here it lights the foot, where there is only the link. */
.product-card::after {
    content: '';
    position: absolute;
    bottom: -48%;
    left: 50%;
    width: 92%;
    aspect-ratio: 1 / 1;
    transform: translateX(-50%);
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--accent-rgb), 0.17), transparent 70%);
    pointer-events: none;
}

/* The glow is absolutely positioned, so without this it would paint over
   the text rather than behind it. */
.product-card > * { position: relative; }

.product-card:hover {
    border-color: var(--accent);
    transform: translateY(-4px);
    box-shadow: 0 22px 44px -28px rgba(0, 0, 0, 0.7);
}

/* The card's title is a lockup: the product's own mark, then its name.
   Every mark is a square 400x400 file, so one fixed box holds all six and
   the line under them starts at the same height on every card in a row —
   which a set of wordmarks, each with its own proportions, could not do.

   The wide wordmarks this replaced (vestra.svg, brolyz.svg) already carried
   these same marks beside their letterforms, so keeping both would have
   drawn one mark twice on the same card.

   Stacked and centred: the mark sits on the card's axis with the name
   directly under it, so the eye reads the picture first and the word
   second rather than sweeping across a row. */
.product-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-bottom: 22px;
    text-align: center;
}

.product-icon {
    flex: none;
    width: 64px;
    height: 64px;
    display: block;
}

/* Manrope rather than the page's own display face, and the only place it
   is used. The mark above it already carries the product's weight, so the
   name is set to read rather than to shout: 600 instead of the 800 the
   other headings take, and smaller than the heading scale would give it.

   Tracking is eased back at the lighter weight — negative tracking closes
   up a thin face faster than a heavy one, and -0.03em had the letters
   touching at this size. */
.product-brand .brand-text {
    font-family: 'Manrope', var(--display);
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -0.015em;
    line-height: 1.15;
    color: var(--text);

    /* Room for two lines whether or not the name needs them. Only Brolyz
       fits on one, and without the reserved line its card started its role
       label a line higher than the five beside it — the eye reads that as
       the cards being out of step rather than as one name being shorter.

       min-height rather than height: a narrow window can push a long name
       onto a third line, and a fixed box would run it into the label. */
    min-height: calc(2em * 1.15);
}

/* The bracketed short name is set in its own product's colour, brackets
   included, so a card carries its identity in the name as well as in the
   mark above it. Taking the brackets in is what makes it read as one
   coloured object rather than as a word with grey punctuation clamped
   either side of it.

   Every value is sampled from the product's own artwork rather than chosen
   by eye, which is the same rule site.css states for the palette at large:
     CMLE  #ED1F25  the wordmark's red — the mark itself is greyscale, so
                    the colour is taken from img/wordmark.png
     VSTR  #FB923C  icon-vstr.svg, the light stop of its gradient
     VUC   #ED9400  icon-vestran.svg, the deep gold of its gradient; the
                    same file also holds a pale #FFDE74 if this reads heavy
     ORTA  #23AD7D  icon-orta.svg, a single flat fill
     GIBI  #FED741  icon-gibi.svg, a single flat fill

   Brolyz has no abbreviation and therefore no rule — its card is the one
   whose name is already the short name. */
.brand-abbr { color: var(--brand-abbr); }

.abbr-cmle { --brand-abbr: #ED1F25; }
.abbr-vstr { --brand-abbr: #FB923C; }
.abbr-vuc  { --brand-abbr: #ED9400; }
.abbr-orta { --brand-abbr: #23AD7D; }
.abbr-gibi { --brand-abbr: #FED741; }

.product-role {
    display: block;
    margin-bottom: 12px;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
}

.product-card p { margin: 0; font-size: 15.5px; line-height: 1.72; color: var(--text-2); }

/* Tier table: name / quantity / points for each tier of the collection. */
.product-tiers {
    width: 100%;
    margin-top: 18px;
    border-top: 1px solid var(--border);
    border-collapse: collapse;
    font-family: var(--mono);
    font-size: 12px;
    color: var(--muted);
}

.product-tiers th,
.product-tiers td {
    padding: 8px 2px;
    text-align: right;
}

.product-tiers th:first-child,
.product-tiers td:first-child {
    text-align: left;
    color: var(--text-2);
}

.product-tiers th {
    padding-top: 14px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-2);
}

.product-tiers tbody tr:not(:last-child) td {
    border-bottom: 1px solid var(--border);
}

.product-link {
    margin-top: 20px;
    font-size: 14px;
    font-weight: 600;
    color: var(--accent);
}

.product-link:hover { text-decoration: underline; }

/* The link leans on the card's bottom edge: so links line up at the same
   height across cards with paragraphs of different lengths. */
.product-footer { margin-top: auto; }

/* ---------- 02 · areas of focus ---------- */

.focus-cards {
    display: grid;
    gap: 16px;
    grid-template-columns: 1fr;
}

@media (min-width: 720px)  { .focus-cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .focus-cards { grid-template-columns: repeat(3, 1fr); } }

/* Individual bordered boxes rather than the hairline-joined grid other
   sections use, since these six are a flat catalogue rather than a set of
   paired or ranked items. The border itself never changes on hover — the
   frame somebody sees is drawn by the light lines in ::before instead. */
.focus-card {
    position: relative;
    padding: clamp(22px, 2.4vw, 28px);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    /* A second, diagonal layer sits behind the card's own colour, parked
       fully off in its top-left corner until hover pulls it through. */
    background:
        linear-gradient(115deg,
            transparent 0%, transparent 42%,
            rgba(var(--accent-rgb), 0.30) 50%,
            transparent 58%, transparent 100%)
        no-repeat,
        var(--card);
    background-size: 320% 320%, 100% 100%;
    background-position: -110% -110%, 0 0;
    transition: transform 0.3s ease, box-shadow 0.3s ease,
        background-position 0.9s ease;
}

/* Three light lines on one element, as three background layers: the top one
   is always lit, the two down the sides are laid out identically but drawn
   at zero height until hover gives them their full length. One element
   rather than three, because an element only has two pseudo-elements and
   the corner glow below needs the other one.

   The side lines are positioned centre-left and centre-right, so growing
   their height opens them out from the middle in both directions — the
   same shape as the top line, whose gradient is also brightest in the
   middle and fades away at both ends. */
.focus-card::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image:
        linear-gradient(90deg, transparent, var(--accent), transparent),
        linear-gradient(180deg, transparent, var(--accent), transparent),
        linear-gradient(180deg, transparent, var(--accent), transparent);
    background-repeat: no-repeat;
    background-size: 100% 2px, 2px 0%, 2px 0%;
    background-position: left top, left center, right center;
    transition: background-size 0.5s ease;
}

.focus-card::after {
    content: '';
    position: absolute;
    top: -45%;
    right: -25%;
    width: 65%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--accent-rgb), 0.14), transparent 70%);
    pointer-events: none;
}

/* Hover: the two side lines open out to full height, so the single line
   along the top becomes a frame on three sides — the same thin ray, just
   more of it. The card lifts, and the diagonal layer sweeps through like a
   ray of light catching it at an angle. */
.focus-card:hover::before {
    background-size: 100% 2px, 2px 100%, 2px 100%;
}

.focus-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 22px 44px -28px rgba(0, 0, 0, 0.7);
    background-position: 10% 10%, 0 0;
}

.focus-card h4 {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 10px;
    font-size: 17px;
    letter-spacing: -0.01em;
}

/* The same accent-square mark the other card grids on this page use,
   turned into a diamond on hover so the card visibly answers a touch. */
.focus-card h4::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 2px;
    background: var(--accent);
    transition: transform 0.3s ease;
}

.focus-card:hover h4::before {
    transform: rotate(45deg) scale(1.4);
}

.focus-card p {
    margin: 0;
    font-size: 15px;
    line-height: 1.68;
    color: var(--text-2);
}

/* ---------- 04 · collection, parallax ---------- */

.parallax {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 54vh;
    padding: clamp(48px, 6.5vh, 84px) 0;
    /* The image is given inline in the HTML. Passing it through a custom
       property was tried and did not work: a relative path inside var() is
       resolved against the stylesheet that uses the var(), not the document
       that declared the variable — the path became css/img/... and 404'd.
       An inline style resolves against the document, which is the behaviour
       a reader would expect. */
    background-size: cover;
    background-position: center;
    background-attachment: fixed;
    overflow: hidden;
}

/* On touch devices a fixed background either flickers or does not work at
   all; it falls back to normal scrolling there. */
@media (hover: none), (max-width: 760px) {
    .parallax { background-attachment: scroll; }
}

/* Reading the text is not left to chance on the photo: the darkening layer
   gives the same contrast on every image, whatever photo ends up behind
   it. */
.parallax::before {
    content: "";
    position: absolute;
    inset: 0;
    /* Since the text is centred, the darkening also opens outward from the
       centre: directly behind the text is the darkest point, faces at the
       edges stay visible. A left-to-right gradient was right back when the
       text sat on the left. */
    background:
        radial-gradient(125% 95% at 50% 50%,
            rgba(10, 12, 16, 0.94) 0%,
            rgba(10, 12, 16, 0.87) 42%,
            rgba(10, 12, 16, 0.58) 100%);
}

.parallax > .wrap { position: relative; z-index: 1; width: 100%; }

/* A passage meant to be read, so it takes body type and a reading measure
   rather than the display type the rest of the page uses for statements.
   Justified under the centred section heading, the same pairing the other
   section heads use: a heading is one line finding its own middle, a
   paragraph is a block and a block reads as one when both edges are
   straight. */
.parallax-note {
    max-width: 72ch;
    margin: 0 auto;
}

.parallax-note p {
    margin: 0 0 16px;
    text-align: justify;
    font-size: 16px;
    line-height: 1.78;
    color: var(--text-2);
}

.parallax-note p:last-child { margin-bottom: 0; }

/* ---------- hero fixes ---------- */

/* The right side of the hero is no longer a single photo but a
   self-rotating strip of cards showing the ecosystem brands. Every card is
   absolutely positioned and stacked on the centre; JS writes an --o
   (offset) and a --d (absolute distance) onto each card relative to the
   active one, and CSS works out the rest from those two variables — so the
   same rule holds whatever the card count (6 today). */
.hero-cards {
    position: relative;
    height: clamp(260px, 32vw, 360px);
}

.hero-card {
    position: absolute;
    top: 50%;
    left: 50%;
    width: clamp(220px, 20vw, 300px);
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    /* --o is signed: negative on the left, positive on the right. --d is
       always positive and says how many cards away from the active one
       (itself included) a card is. Past 2 the scale/opacity is clamped so
       far cards do not collapse to nothing, they just stay invisible — the
       rotation keeps going in the background. */
    transform:
        translate(-50%, -50%)
        translateX(calc(var(--o, 0) * 78%))
        scale(calc(1 - 0.68 * min(var(--d, 0), 2)));
    opacity: calc(1 - 0.5 * min(var(--d, 0), 2));
    filter: saturate(calc(1 - 0.35 * min(var(--d, 0), 2)));
    z-index: calc(10 - var(--d, 0));
    pointer-events: none;
    transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.8s ease, filter 0.8s ease;
}

.hero-card.is-active {
    pointer-events: auto;
}

.hero-card-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.hero-card-brand img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }

.hero-card-brand .brand-text {
    font-family: var(--display);
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
    .hero-card { transition: none; }
}

/* ---------- form ---------- */

.block .contact-form { margin: 0 auto; max-width: 720px; }
