/* ==========================================================================
   websites-2027.css — page-specific rules for /websites
   --------------------------------------------------------------------------
   Depends on, and never re-declares, two files loaded before it:

     css/site-2027.css   tokens, chrome, buttons, eyebrows, section rhythm,
                         hairline rows, cards, the .cy27-shot slot and the
                         `.cy27-shot img` fitting rule that every installed
                         capture on this page relies on, the accordion, the
                         beam panel, the reveal utility
     css/media-2027.css  phone frames, screenshot carousels, the scripted
                         screencast player

   Only what those two cannot express is here: the split hero and its browser
   frame, the four-job card row, the site-type picker, and the section-level
   spacing this page's compositions need.

   No !important. No bare descendant-element resets at page scope — a rule
   like `.cy27-page p {}` scores 0,1,1 and silently outranks every
   single-class rule in the shared layer, which collapses the spacing scale.
   Element selectors below are always scoped to a .cy27-web* component, which
   is the same pattern the shared file uses for .cy27-row p.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Utilities
   -------------------------------------------------------------------------- */

/* Duplicated from css/pricing-2027.css, which is not loaded here. It belongs
   in site-2027.css once someone is editing that file for another reason. */
.cy27-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    border: 0;
    white-space: nowrap;
    clip-path: inset(50%);
}


/* --------------------------------------------------------------------------
   1. No-JS safety net
   --------------------------------------------------------------------------
   Two mechanisms on this page hide content that only script can bring back:
   the accordion (max-height:0) and the site-type picker (four of five panels
   carry [hidden]). `.no-js` is stamped on <html> and removed by the inline
   script at the top of <head>, so everything below applies only when
   scripting is genuinely off.

   The trigger's aria-expanded stays "false" while the panel is visible here.
   That mismatch is the accepted trade — the same one css/faq-2027.css makes —
   because an unreadable answer is a far worse failure than a stale state
   attribute on a control that cannot be operated anyway.
   -------------------------------------------------------------------------- */

.no-js .cy27-acc__panel {
    max-height: none;
}

/* A chevron pointing at an already-open panel just reads as broken. */
.no-js .cy27-webfaq__chev {
    display: none;
}

/* The rail is five buttons that cannot do anything without script, so it goes
   and every panel is shown stacked instead. Nothing is lost: each panel
   already carries its own name, price and timeline. */
.no-js .cy27-webtypes__grid {
    grid-template-columns: 1fr;
}

.no-js .cy27-webtypes__rail {
    display: none;
}

/* 0,3,0 — clears both the UA [hidden] rule and the 0,2,0 rule in §4. */
.no-js .cy27-webtypes__panel[hidden] {
    display: block;
}

.no-js .cy27-webtypes__panel + .cy27-webtypes__panel {
    margin-top: 40px;
    padding-top: 40px;
    border-top: 1px solid var(--cy27-line);
}


/* --------------------------------------------------------------------------
   2. Hero — copy left, screencast + offset phone right
   -------------------------------------------------------------------------- */

/* Design: 1.05fr .95fr, gap 64, vertically centred, 110px of tail. The shared
   split hero is 1.1fr .9fr, gap 56, top-aligned, 120px. Equal specificity to
   .cy27-phero--split .cy27-phero__inner (0,2,0); this file loads later. */
.cy27-webhero .cy27-phero__inner {
    grid-template-columns: 1.05fr .95fr;
    gap: 64px;
    align-items: center;
    padding-bottom: 110px;
}

.cy27-webhero .cy27-phero__eyebrow {
    margin-bottom: 22px;
}

/* 0,2,0 so it clears .cy27-page h1 (0,1,1) without an element selector. */
.cy27-page .cy27-webhero__title {
    font-size: clamp(2.3rem, 4.4vw, 4rem);
    line-height: 1.03;
    margin-bottom: 26px;
}

.cy27-webhero .cy27-phero__lead {
    max-width: 560px;
    margin-bottom: 34px;
}

.cy27-webhero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 32px;
}

.cy27-webhero__trust {
    display: grid;
    grid-template-columns: repeat(2, auto);
    justify-content: start;
    gap: 10px 32px;
    font-family: var(--cy27-mono);
    font-size: .76rem;
    letter-spacing: .06em;
    color: var(--cy27-subtle);
}

/* The positioning context for the offset phone, which deliberately hangs
   outside the browser frame's rounded corners. */
.cy27-webhero__media {
    position: relative;
}

/* -- Browser chrome --------------------------------------------------------
   NOT .cy27-frame. That block still lives in css/home-2027.css, which this
   page does not load, and promoting it is a shared-file edit outside this
   task. Two further reasons not to reach for it if it does get promoted:
   .cy27-frame__shot hard-codes aspect-ratio 16/11, which would fight the
   --cy27-demo-ratio custom property the screencast reads, and this hero's
   frame is 16px-radius where the home page's is 14px.
   -------------------------------------------------------------------------- */

/* The screencast's provenance badge ("real capture · autoplay") sits bottom-
   RIGHT by default, which on this page is exactly where the offset phone hangs
   off the frame's corner. Combined with .cy27-webframe's stacking context —
   which correctly lets the phone paint above the demo's cursor and ripple — the
   badge was completely covered: measured at 1440px it sat at x 1122-1299,
   y 627-650, entirely inside the phone's box, with the phone's <img> topmost.
   A label nobody can read cannot do its job, so on this page it moves left,
   clear of the phone. apps.html has no offset phone and keeps the default. */
.cy27-webhero__demo .cy27-demo__badge {
    right: auto;
    left: 12px;
}

.cy27-webframe {
    /* A stacking context, not a positioning trick: the screencast injects a
       cursor, ripple and corner badge at z-index 3-4 (media-2027.css), and
       with nothing between them and the root they paint over the offset
       phone that hangs off this frame's corner. z-index:0 traps those layers
       inside the browser window so the later-in-tree phone stays on top. */
    position: relative;
    z-index: 0;
    border: 1px solid rgba(255, 255, 255, .09);
    border-radius: 16px;
    overflow: hidden;
    background: linear-gradient(160deg, rgba(20, 27, 40, .72), rgba(11, 16, 25, .6));
    box-shadow: 0 28px 70px rgba(0, 0, 0, .5);
}

.cy27-webframe__bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.cy27-webframe__dot {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .16);
}

.cy27-webframe__url {
    margin-left: 12px;
    font-family: var(--cy27-mono);
    font-size: .72rem;
    color: var(--cy27-subtle);
    /* The URL is chrome, not content: never let it push the bar wider. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Websites runs 16/11; Apps runs the module default of 16/10. Set as a custom
   property rather than a plain aspect-ratio so [data-cy27-demo] stays the one
   place the ratio is applied. The four sb-skincare.com captures are authored
   at 1600x1100, i.e. exactly 16/11, so `background-size: cover` has nothing to
   crop on the three un-panned frames. Only frame 1 carries data-pan, and
   media-2027.css gives that one 125% height to drift into — which is what
   makes it, and only it, 20% wider than the frame and cropped side to side. */
.cy27-webhero__demo {
    --cy27-demo-ratio: 16 / 11;
}

/* -- Offset mini phone -----------------------------------------------------
   Not the .cy27-phone primitive from media-2027.css: this is a hero
   composition element with its own 9/16 ratio, a 14px radius and no speaker
   bar. Folding it into .cy27-phone would force every phone frame on the site
   to carry an exception.
   -------------------------------------------------------------------------- */

.cy27-webhero__offset {
    position: absolute;
    right: -18px;
    bottom: -30px;
    width: 52%;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 14px;
    overflow: hidden;
    background: #0b0f17;
    box-shadow: 0 22px 60px rgba(0, 0, 0, .55);
}

/* width:100% is load-bearing, not decoration: an element carrying
   aspect-ratio with no definite width back-computes the width from its
   height, and anything that later imposes a min-height would then blow the
   panel wider than its 52% column. */
/* 9/16 matches the two 640x1138 phone captures installed in this carousel, so
   `.cy27-shot img`'s object-fit: cover crops nothing. Change one and change
   the other, or the phone screens start losing a band off the bottom. */
.cy27-webhero__offset-screen {
    width: 100%;
    aspect-ratio: 9 / 16;
}


/* --------------------------------------------------------------------------
   3. Four jobs a Cybrid site does
   -------------------------------------------------------------------------- */

.cy27-webjobs__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webjobs__title {
    max-width: 760px;
    margin-bottom: 44px;
}

/* An <ol> because the four jobs are explicitly ranked. The list reset is
   scoped to this class rather than written as a bare `ol` rule. */
.cy27-webjobs__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 22px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.cy27-webjobs__card {
    padding: 30px 26px;
}

.cy27-webjobs__num {
    display: block;
    margin-bottom: 16px;
    font-family: var(--cy27-mono);
    font-size: .72rem;
    color: var(--cy27-accent);
}

/* 0,1,1 — ties .cy27-page h3 and wins on source order, which is why this file
   must stay after site-2027.css in the <head>. */
.cy27-webjobs__card h3 {
    margin-bottom: 10px;
    font-size: 1.15rem;
    letter-spacing: -.015em;
}

.cy27-webjobs__card p {
    font-size: .95rem;
    line-height: 1.7;
    color: var(--cy27-body);
}


/* --------------------------------------------------------------------------
   4. Site types — the picker
   --------------------------------------------------------------------------
   A 280px rail of aria-pressed buttons beside one detail panel. Every panel
   ships in the markup; the inactive ones carry [hidden] so they leave the
   accessibility tree along with the layout. js/websites-2027.js owns swapping
   [hidden] and aria-pressed, and the arrow-key movement between buttons; the
   markup ships with aria-pressed already correct for the default selection so
   it is never null on load.
   -------------------------------------------------------------------------- */

/* The nav is fixed, so an in-page jump to #types would otherwise land under
   it. Matches the design's 110px. */
.cy27-webtypes {
    scroll-margin-top: 110px;
}

.cy27-webtypes__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webtypes__title {
    max-width: 760px;
    margin-bottom: 16px;
}

.cy27-webtypes__lead {
    max-width: 620px;
    margin-bottom: 40px;
}

.cy27-webtypes__grid {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 24px;
    align-items: start;
}

.cy27-webtypes__rail {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* 52px minimum, well past the 44px floor, and it holds even when the rail
   turns into a horizontal scroller below 1000px. */
.cy27-webtypes__btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    width: 100%;
    min-height: 52px;
    padding: 15px 18px;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .09);
    border-radius: 12px;
    color: var(--cy27-body-strong);
    font-family: var(--cy27-sans);
    font-size: .98rem;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    transition: background .25s ease, border-color .25s ease, color .25s ease;
}

.cy27-webtypes__btn:hover {
    border-color: rgba(255, 255, 255, .2);
    color: var(--cy27-heading);
}

/* Selection is expressed through aria-pressed alone — there is no parallel
   `is-active` class to fall out of sync with the accessibility tree. */
.cy27-webtypes__btn[aria-pressed="true"] {
    background: rgba(0, 192, 250, .12);
    border-color: rgba(0, 192, 250, .4);
    color: var(--cy27-heading);
}

.cy27-webtypes__btn-name {
    white-space: nowrap;
}

.cy27-webtypes__btn-price {
    flex: 0 0 auto;
    font-family: var(--cy27-mono);
    font-size: .74rem;
    font-weight: 400;
    color: var(--cy27-subtle);
    white-space: nowrap;
}

.cy27-webtypes__btn[aria-pressed="true"] .cy27-webtypes__btn-price {
    color: var(--cy27-accent);
}

.cy27-webtypes__panels {
    padding: 38px 36px;
    /* Keeps the panel from resizing as the copy length changes between types.
       Safe alongside no aspect-ratio here — the min-height/aspect-ratio
       overflow trap needs both. */
    min-height: 400px;
}

/* Written explicitly so [hidden] cannot be defeated later: the UA rule is
   only 0,1,0, so any single-class `display` on this element would beat it. */
.cy27-webtypes__panel[hidden] {
    display: none;
}

.cy27-webtypes__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px;
    margin-bottom: 14px;
}

/* 0,2,0 to clear .cy27-page h3 (0,1,1) — this heading is a panel title, not a
   card title, and wants the larger cut. */
.cy27-page .cy27-webtypes__name {
    font-size: 1.6rem;
    font-weight: 800;
    letter-spacing: -.02em;
}

.cy27-webtypes__meta {
    font-family: var(--cy27-mono);
    font-size: .8rem;
    color: var(--cy27-accent);
}

.cy27-webtypes__copy {
    max-width: 560px;
    margin-bottom: 26px;
    font-size: 1.05rem;
    line-height: 1.7;
    color: var(--cy27-body);
}

.cy27-webtypes__incl {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 32px;
    margin-bottom: 28px;
}

.cy27-webtypes__incl li {
    padding: 9px 0;
    border-top: 1px solid var(--cy27-line);
    color: var(--cy27-body-strong);
    font-size: .95rem;
}

.cy27-webtypes__fit {
    font-family: var(--cy27-mono);
    font-size: .76rem;
    letter-spacing: .06em;
    line-height: 1.6;
    color: var(--cy27-subtle);
}


/* --------------------------------------------------------------------------
   5. Included every time
   -------------------------------------------------------------------------- */

.cy27-webincl__grid {
    display: grid;
    grid-template-columns: .85fr 1.15fr;
    gap: 64px;
    align-items: start;
}

.cy27-webincl__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webincl__intro h2 {
    margin-bottom: 20px;
}

/* Design: a 170px label column, 24px gutter, 22px rows — tighter than the
   shared .cy27-row--split (.32fr / 32px / 28px). See §11 for the matching
   collapse; a 0,2,0 override written out here would otherwise outrank the
   shared 0,1,0 stacking rule inside the ≤1000px block and keep a 170px
   column on a phone. */
.cy27-webincl__rows .cy27-row--split {
    grid-template-columns: 170px 1fr;
    gap: 24px;
    padding: 22px 0;
}

/* These rows are the page's "this is what you get" list, so they read one
   step brighter than the shared body colour. */
.cy27-webincl__rows .cy27-row p {
    font-size: .98rem;
    color: var(--cy27-body-strong);
}


/* --------------------------------------------------------------------------
   6. Mobile first, not mobile last
   -------------------------------------------------------------------------- */

.cy27-webmobile__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webmobile__title {
    max-width: 820px;
    margin-bottom: 16px;
}

.cy27-webmobile__lead {
    max-width: 640px;
    margin-bottom: 48px;
}

/* .cy27-phones sets `margin: 0 auto`; a longhand declared later wins for that
   one side without disturbing the auto centring. */
.cy27-webmobile__phones {
    margin-bottom: 56px;
}

.cy27-webmobile__rows {
    grid-template-columns: 1fr 1fr;
    gap: 0 56px;
    max-width: 1000px;
    margin: 0 auto;
}

.cy27-webmobile__rows .cy27-row--split {
    grid-template-columns: 150px 1fr;
    gap: 20px;
    padding: 20px 0;
}

.cy27-webmobile__rows .cy27-row p {
    font-size: .95rem;
    color: var(--cy27-body-strong);
}

/* The shared `:last-child` bottom border closes exactly one row. In two
   columns that leaves the bottom of the LEFT column hanging open, so close
   the final two. Undone again at ≤1000px, where the grid is one column and
   this would double the hairline between rows five and six. */
.cy27-webmobile__rows > .cy27-row:nth-last-child(-n + 2) {
    border-bottom: 1px solid rgba(255, 255, 255, .09);
}


/* --------------------------------------------------------------------------
   7. Recent websites — single stills on purpose, no carousel
   -------------------------------------------------------------------------- */

.cy27-webrecent__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webrecent__title {
    max-width: 760px;
    margin-bottom: 44px;
}

.cy27-webrecent__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 22px;
}

.cy27-webrecent__card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* width:100% again pairs with aspect-ratio — see the note in §2. 4/3 is also
   the exact ratio the three 1000x750 captures are authored at, so nothing is
   cropped; the shared `.cy27-shot img` rule does the fitting. */
.cy27-webrecent__shot {
    width: 100%;
    aspect-ratio: 4 / 3;
}

.cy27-webrecent__body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 26px 24px;
}

.cy27-webrecent__body h3 {
    margin: 12px 0 10px;
    font-size: 1.15rem;
    letter-spacing: -.015em;
}

.cy27-webrecent__body p {
    margin-bottom: 18px;
    font-size: .94rem;
    line-height: 1.7;
    color: var(--cy27-body);
}

/* min-height carries the 44px target: the link is the card's only control and
   its single line of text is nowhere near that tall on its own. */
.cy27-webrecent__link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    font-size: .92rem;
    font-weight: 700;
}

.cy27-webrecent__link i {
    font-size: .72rem;
}


/* --------------------------------------------------------------------------
   8. Process
   -------------------------------------------------------------------------- */

.cy27-webprocess__grid {
    display: grid;
    grid-template-columns: .85fr 1.15fr;
    gap: 64px;
    align-items: start;
}

.cy27-webprocess__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webprocess__intro h2 {
    margin-bottom: 20px;
}

.cy27-webprocess__steps {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Deliberately does NOT restate grid-template-columns. The shared .cy27-row
   is already 64px 1fr, and a 0,2,0 copy here would outrank the shared ≤760px
   rule that stacks the numeral above the step. The gap below is exactly that
   kind of copy, so §11 restates the ≤760px value at matching specificity. */
.cy27-webprocess__steps .cy27-row {
    gap: 24px;
    padding: 26px 0;
}

/* The shared numeral is an uppercase micro-label; the process wants it read
   as a figure. */
.cy27-webprocess__steps .cy27-row__num {
    font-size: .9rem;
    letter-spacing: .05em;
    padding-top: .2em;
}

.cy27-webprocess__steps .cy27-row h3 {
    margin-bottom: 8px;
    font-size: 1.2rem;
}

.cy27-webprocess__steps .cy27-row p {
    font-size: .98rem;
}


/* --------------------------------------------------------------------------
   9. Website questions
   -------------------------------------------------------------------------- */

.cy27-webfaq__eyebrow {
    display: block;
    margin-bottom: 16px;
}

.cy27-webfaq__title {
    max-width: 760px;
    margin-bottom: 40px;
}

.cy27-webfaq__list {
    max-width: 900px;
}

/* Each question is a real heading for document outline and screen-reader
   navigation, but it must not take the h3 type ramp — the trigger inside it
   owns the visual treatment. 0,2,0 to clear .cy27-page h3 (0,1,1). */
.cy27-page .cy27-webfaq__h {
    font-size: inherit;
    font-weight: inherit;
}

/* The design's chevron is not in the FontAwesome subset — css/icons-2027.css
   ships 70 glyphs and regenerating it means editing a shared file — so the
   arrow is drawn in CSS instead.

   TRAP: the 45deg rotation lives on ::before, never on the <i>. The shared
   rule `.cy27-acc__trigger[aria-expanded="true"] i` sets
   `transform: rotate(180deg)`, which REPLACES a transform written on the <i>
   rather than composing with it — the chevron would snap to a nonsense angle
   on open. Rotating the box and the glyph on separate elements keeps both. */
.cy27-webfaq__chev {
    flex: 0 0 auto;
    display: inline-grid;
    place-items: center;
    width: 14px;
    height: 14px;
}

.cy27-webfaq__chev::before {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--cy27-accent);
    border-bottom: 2px solid var(--cy27-accent);
    /* -2px lifts the optical centre: a chevron's mass sits below its box. */
    transform: translateY(-2px) rotate(45deg);
}


/* --------------------------------------------------------------------------
   10. Final CTA
   -------------------------------------------------------------------------- */

/* 140px rather than the shared 130px — the last panel before the footer gets
   the extra air, and this is the only place on the page that departs from the
   shared section rhythm. */
.cy27-webcta {
    padding-bottom: 140px;
}

.cy27-webcta__panel {
    padding: clamp(40px, 6vw, 84px) clamp(24px, 5vw, 64px);
    border-radius: 20px;
    text-align: center;
}

.cy27-webcta__panel h2 {
    margin-bottom: 16px;
}

.cy27-webcta__lead {
    max-width: 540px;
    margin: 0 auto 32px;
    font-size: 1.1rem;
    line-height: 1.7;
    color: var(--cy27-body);
}

.cy27-webcta__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
}

.cy27-webcta__note {
    margin-top: 28px;
    font-family: var(--cy27-mono);
    font-size: .74rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--cy27-subtle);
}


/* --------------------------------------------------------------------------
   11. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
    /* Hero stacks. The shared .cy27-phero already drops the top padding to
       126px at this width; only the columns and the tail are ours. */
    .cy27-webhero .cy27-phero__inner {
        grid-template-columns: 1fr;
        gap: 44px;
        padding-bottom: 64px;
    }

    /* The offset phone stops overlapping and sits under the frame, centred.
       Left hanging it would push past the container gutter on a narrow
       viewport. */
    .cy27-webhero__offset {
        position: static;
        width: 100%;
        max-width: 260px;
        margin: 20px auto 0;
    }

    /* The design collapses its 2- and 3-column grids here but leaves the
       four job cards at four across, which puts them near 170px wide — an
       oversight rather than a choice, since the same file collapses them at
       760px. Two across is the repair. */
    .cy27-webjobs__grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .cy27-webtypes__grid {
        grid-template-columns: 1fr;
    }

    /* The rail becomes a horizontal strip. flex:0 0 auto stops the five
       buttons from being squeezed to nothing, and the padding leaves room
       for an overlay scrollbar without clipping the focus ring.
       The padding has to be symmetric: overflow-x:auto against an
       overflow-y:visible computes the y axis to auto too, so the rail clips
       on BOTH axes and a bottom-only pad would still shear the top of every
       button's focus outline. The negative margin gives the extra 6px back
       so nothing below shifts. */
    .cy27-webtypes__rail {
        flex-direction: row;
        overflow-x: auto;
        gap: 8px;
        padding: 6px 0;
        margin-top: -6px;
    }

    .cy27-webtypes__btn {
        flex: 0 0 auto;
        width: auto;
    }

    .cy27-webincl__grid,
    .cy27-webprocess__grid {
        grid-template-columns: 1fr;
        gap: 32px;
    }

    /* TRAP: the 0,2,0 overrides in §5 and §6 outrank the shared 0,1,0 rule
       that stacks .cy27-row--split at this width, so the collapse has to be
       restated at matching specificity or a 170px label column survives onto
       a phone. */
    .cy27-webincl__rows .cy27-row--split,
    .cy27-webmobile__rows .cy27-row--split {
        grid-template-columns: 1fr;
        gap: 10px;
    }

    .cy27-webrecent__grid {
        grid-template-columns: 1fr;
    }

    /* One column again, so the two-column bottom-border fix from §6 has to be
       undone — otherwise rows five and six meet on a doubled hairline. */
    .cy27-webmobile__rows {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .cy27-webmobile__rows > .cy27-row:nth-last-child(-n + 2) {
        border-bottom: 0;
    }

    .cy27-webmobile__rows > .cy27-row:last-child {
        border-bottom: 1px solid rgba(255, 255, 255, .09);
    }
}

@media (max-width: 760px) {
    .cy27-webhero__trust {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .cy27-webjobs__grid {
        grid-template-columns: 1fr;
    }

    .cy27-webtypes__panels {
        padding: 28px 22px;
        /* The reserved height only exists to stop the panel jumping as types
           are swapped; on one column it is just dead space. */
        min-height: 0;
    }

    .cy27-webtypes__head {
        gap: 4px;
    }

    .cy27-webtypes__incl {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .cy27-webincl__grid,
    .cy27-webprocess__grid {
        gap: 28px;
    }

    /* Same trap as the ≤1000px block above: §8's 0,2,0 gap outranks the
       shared 0,1,0 rule that drops .cy27-row to 10px once the numeral stacks
       over the step, so a 24px hole survives between them on a phone unless
       the collapse is restated at matching specificity. */
    .cy27-webprocess__steps .cy27-row {
        gap: 10px;
    }

    .cy27-webcta__note {
        letter-spacing: .06em;
    }
}


/* --------------------------------------------------------------------------
   12. Reduced motion
   --------------------------------------------------------------------------
   The shared layer already stills the beam, the reveals, the button lift and
   the accordion; media-2027.css stills the carousel and screencast. The rail
   button is the only transition this file introduces.
   -------------------------------------------------------------------------- */

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