/* Homepage top projects (index.html): the Design System card's component
   board and the Page Templates wireframe deck. The shared card styles (.cs-tldr--home,
   .cs-tldr__visual) live in style.css; this file only adds what these two
   cards need. Loaded by index.html only. */

#project-design-system .cs-tldr--home {
    --homeAccent: #7122ec;
}

/* FNZ and Appway share the brand row. Appway's wordmark is much wider, so it
   gets a lower cap to sit at roughly the same visual weight as FNZ. */
.cs-tldr--home .cs-tldr__header .topLogo--fnz {
    max-height: 22px;
}

.cs-tldr--home .cs-tldr__header .topLogo--appway {
    max-height: 20px;
}

/* --- Design System: component definitions on an isometric board -----------
   Redlined specs from the design system docs (each part of a component
   numbered), laid out as frames on a plane tilted like the case-study
   illustration. The plane stays flat (no preserve-3d: Chrome hit-tests cards
   in a 3D context unreliably, and they need to take clicks), so a hovered
   card "lifts" by sliding along the plane's diagonal that points straight up
   on screen, (1, -1), leaving its shadow on the board. As the card scrolls through the viewport the rows slide
   past each other (scroll-driven, no script); elsewhere they sit still.
   The rows are centred and grow towards the middle, a diamond on the plane
   that projects to a rectangle covering the whole card. Clicking a spec opens
   it full size (ds-specs.js).
   Weight: the board is one 35 KB sprite (8 × 5 cells of 256 × 160, padding
   baked in), requested only once the card nears the viewport (.is-near, set
   by ds-specs.js). Full-size specs load one at a time, in the viewer. */
.dsSpecs {
    --ds-card-w: 21cqw;
    --ds-ease: cubic-bezier(0.22, 1, 0.36, 1);
    position: relative;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    container-type: inline-size;
    view-timeline: --dsSpecs block;
    line-height: 1.2;
    background:
        radial-gradient(circle, color-mix(in srgb, var(--homeAccent) 26%, transparent) 1px, transparent 1.5px) 0 0 / 20px 20px,
        linear-gradient(170deg, color-mix(in srgb, var(--homeAccent) 4%, #fff), color-mix(in srgb, var(--homeAccent) 14%, #fff));
}

.dsSpecs__plane {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.4cqw;
    transform: translate(-50%, -50%) rotateX(56deg) rotateZ(-45deg);
    transition: transform 1.1s var(--ds-ease);
}

.topProject:hover .dsSpecs__plane {
    transform: translate(-50%, -50%) rotateX(50deg) rotateZ(-40deg) scale(1.05);
}

.dsSpecs__row {
    display: flex;
    gap: 2.4cqw;
    width: max-content;
}

.dsSpecs__row:hover {
    z-index: 1;
}

.dsSpecs__card {
    flex: none;
    width: var(--ds-card-w);
    margin: 0;
    padding: 0;
    transition: transform 0.5s var(--ds-ease);
    cursor: zoom-in;
}

/* The hovered frame rises off the board, name and all. */
.dsSpecs__card:hover {
    z-index: 1;
    transform: translate(1.4cqw, -1.4cqw) scale(1.1);
}

/* Frame name, the way Figma labels a frame above its corner. */
.dsSpecs__card figcaption {
    margin: 0 0 0.7cqw;
    padding: 0;
    overflow: hidden;
    color: color-mix(in srgb, var(--homeAccent) 75%, #050038);
    font-family: var(--font-meta, ui-monospace, monospace);
    font-size: max(8px, 1.25cqw);
    line-height: 1.2;
    text-align: left;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.dsSpecs__frame {
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background-color: #fff;
    background-repeat: no-repeat;
    background-size: 800% 500%;
    background-position: calc(var(--c) / 7 * 100%) calc(var(--r) / 4 * 100%);
    border-radius: 0.8cqw;
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--homeAccent) 16%, transparent),
        0.4cqw 0.6cqw 0 color-mix(in srgb, var(--homeAccent) 10%, transparent);
    transition: box-shadow 0.5s var(--ds-ease);
}

.dsSpecs.is-near .dsSpecs__frame {
    background-image: url("../../work/media/DesignSystem/definitions/sprite.webp");
}

.dsSpecs__card:hover .dsSpecs__frame {
    box-shadow:
        0 0 0 1.5px var(--homeAccent),
        -1.8cqw 1.8cqw 1.6cqw -0.4cqw color-mix(in srgb, var(--homeAccent) 38%, transparent);
}

/* The keyboard way in: the site's "See all" pill, on the board's corner. */
.dsSpecs__actions {
    position: absolute;
    left: 14px;
    bottom: 14px;
    z-index: 2;
}

.dsSpecs:not(.is-ready) .dsSpecs__actions {
    display: none;
}

.dsSpecs .cs-carousel__see-all {
    border-color: var(--frgd) !important;
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .dsSpecs__row {
            animation: dsSpecsDrift linear both;
            animation-timeline: --dsSpecs;
            animation-range: cover 0% cover 100%;
        }

        .dsSpecs__row:nth-child(even) {
            animation-name: dsSpecsDriftBack;
        }
    }
}

@keyframes dsSpecsDrift {
    from { transform: translateX(7cqw); }
    to   { transform: translateX(-7cqw); }
}

@keyframes dsSpecsDriftBack {
    from { transform: translateX(-7cqw); }
    to   { transform: translateX(7cqw); }
}

@media (prefers-reduced-motion: reduce) {
    .dsSpecs__plane,
    .dsSpecs__card,
    .dsSpecs__frame {
        transition: none;
    }

    .topProject:hover .dsSpecs__plane {
        transform: translate(-50%, -50%) rotateX(56deg) rotateZ(-45deg);
    }
}

/* --- Page Templates: a cover-flow of wireframes ---------------------------
   The front sheet scrolls its page top to bottom like a browser tab; when it
   reaches the footer, wireframe-deck.js moves the deck on. Sheets are sized in
   cqw of the deck, so the whole composition scales with the card.
   data-pos is the sheet's distance from the front (-3…3, or "far").
   Weight: every sheet is first painted from one 51 KB strip sprite (all
   twelve pages at 180 px wide), requested once the deck nears the viewport
   (.is-near, wireframe-deck.js). Only the front page and the next one get
   their full image, which fades in over the sprite. */
.wfDeck {
    --wf-sheet-w: 31cqw;
    --wf-sheet-h: 46cqw;
    --wf-dur: 6s;
    --wf-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --wf-ink: var(--frgd, #050038);
    position: relative;
    container-type: inline-size;
    line-height: 1.4;
    background:
        radial-gradient(circle, color-mix(in srgb, var(--homeAccent) 24%, transparent) 1px, transparent 1.5px) 0 0 / 20px 20px,
        linear-gradient(180deg, color-mix(in srgb, var(--homeAccent) 3%, #fff), color-mix(in srgb, var(--homeAccent) 10%, #fff));
}

.wfDeck__stage {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    perspective: 1600px;
    touch-action: pan-y;
}

.wfDeck__slides {
    position: absolute;
    inset: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    transform-style: preserve-3d;
}

.wfDeck__slide {
    --x: 0;
    --s: 1;
    --r: 0deg;
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--wf-sheet-w);
    height: var(--wf-sheet-h);
    margin: 0;
    padding: 0;
    list-style: none;
    z-index: 1;
    opacity: 0;
    visibility: hidden;
    transform:
        translate(-50%, -50%)
        translateX(calc(var(--x) * var(--wf-sheet-w)))
        rotateY(var(--r))
        scale(var(--s));
    transition:
        transform 0.75s var(--wf-ease),
        opacity 0.45s ease,
        visibility 0s linear 0.45s;
    cursor: pointer;
}

.wfDeck__slide[data-pos="0"],
.wfDeck__slide[data-pos="1"],
.wfDeck__slide[data-pos="-1"],
.wfDeck__slide[data-pos="2"],
.wfDeck__slide[data-pos="-2"] {
    opacity: 1;
    visibility: visible;
    transition:
        transform 0.75s var(--wf-ease),
        opacity 0.45s ease,
        visibility 0s linear 0s;
}

.wfDeck__slide[data-pos="0"] {
    z-index: 5;
    cursor: default;
}

.wfDeck__slide[data-pos="-1"] { --x: -0.84; --s: 0.84; --r: 26deg; z-index: 4; }
.wfDeck__slide[data-pos="1"]  { --x: 0.84;  --s: 0.84; --r: -26deg; z-index: 4; }
.wfDeck__slide[data-pos="-2"] { --x: -1.5;  --s: 0.7;  --r: 34deg; z-index: 3; opacity: 0.6; }
.wfDeck__slide[data-pos="2"]  { --x: 1.5;   --s: 0.7;  --r: -34deg; z-index: 3; opacity: 0.6; }
.wfDeck__slide[data-pos="-3"] { --x: -2;    --s: 0.6;  --r: 40deg; }
.wfDeck__slide[data-pos="3"]  { --x: 2;     --s: 0.6;  --r: -40deg; }
.wfDeck__slide[data-pos="far"] { --s: 0.5; }

/* A browser tab: chrome bar with the template's path, then the page. */
.wfDeck__sheet {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #fff;
    border-radius: 1.2cqw;
    box-shadow:
        0 0 0 1px rgba(5, 0, 56, 0.08),
        0 10px 24px -12px rgba(5, 0, 56, 0.3);
    transition: box-shadow 0.5s ease;
}

.wfDeck__slide[data-pos="0"] .wfDeck__sheet {
    box-shadow:
        0 0 0 1px rgba(5, 0, 56, 0.08),
        0 24px 48px -18px color-mix(in srgb, var(--homeAccent) 60%, transparent);
}

/* Sheets behind the front one fade into the board. */
.wfDeck__sheet::after {
    content: "";
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--homeAccent) 6%, #fff);
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.5s ease;
}

.wfDeck__slide[data-pos="0"] .wfDeck__sheet::after {
    opacity: 0;
}

.wfDeck__slide:not([data-pos="0"]):hover .wfDeck__sheet::after {
    opacity: 0.2;
}

.wfDeck__chrome {
    flex: none;
    display: flex;
    align-items: center;
    gap: 0.7cqw;
    height: 3.4cqw;
    padding: 0 1.2cqw;
    background: #f4f3f7;
    border-bottom: 1px solid rgba(5, 0, 56, 0.08);
}

.wfDeck__chrome i {
    flex: none;
    width: 0.9cqw;
    height: 0.9cqw;
    border-radius: 50%;
    background: #d6d4de;
}

.wfDeck__chrome i:first-child {
    background: var(--homeAccent);
}

.wfDeck__chrome span {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0 0 0 0.8cqw;
    padding: 0.25cqw 1cqw;
    overflow: hidden;
    border-radius: 99px;
    background: #fff;
    color: rgba(5, 0, 56, 0.55);
    font-family: var(--font-meta, ui-monospace, monospace);
    font-size: max(9px, 1.3cqw);
    line-height: 1.4;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* The page is a size container, so its image can scroll by exactly
   "image height minus window height" (100% − 100cqh). */
.wfDeck__page {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    container-type: size;
}

/* The whole page at its own aspect ratio; this is what scrolls. */
.wfDeck__shot {
    position: relative;
    aspect-ratio: var(--ar);
    background-color: #fff;
    background-repeat: no-repeat;
    background-size: 1200% var(--sh);
    background-position: calc(var(--i) / 11 * 100%) 0;
}

.wfDeck.is-near .wfDeck__shot {
    background-image: url("../../work/media/Templates/wireframes/sprite.webp");
}

.wfDeck__shot img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    margin: 0;
}

/* Hidden at once, faded in when loaded (the transition is on the loaded state). */
.wfDeck.is-ready .wfDeck__shot img:not(.is-loaded) {
    opacity: 0;
}

.wfDeck__shot img.is-loaded {
    transition: opacity 0.35s ease;
}

.wfDeck__thumb {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 4px;
    height: 22%;
    border-radius: 4px;
    background: rgba(5, 0, 56, 0.3);
    opacity: 0;
    transition: opacity 0.3s ease;
}

.wfDeck__slide[data-pos="0"] .wfDeck__thumb {
    opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
    .wfDeck__slide[data-pos="0"] .wfDeck__shot {
        animation: wfScroll var(--wf-dur) ease-in-out 0.6s 1 both;
    }

    .wfDeck__slide[data-pos="0"] .wfDeck__thumb {
        animation: wfThumb var(--wf-dur) ease-in-out 0.6s 1 both;
    }

    .wfDeck.is-paused .wfDeck__slide[data-pos="0"] .wfDeck__shot,
    .wfDeck.is-paused .wfDeck__slide[data-pos="0"] .wfDeck__thumb {
        animation-play-state: paused;
    }
}

@keyframes wfScroll {
    0%, 8%    { transform: translateY(0); }
    92%, 100% { transform: translateY(calc(-100% + 100cqh)); }
}

@keyframes wfThumb {
    0%, 8%    { transform: translateY(0); }
    92%, 100% { transform: translateY(calc(100cqh - 100% - 6px)); }
}

/* Caption and controls under the stage. */
.wfDeck__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px 10px 18px;
    border-top: 1px solid color-mix(in srgb, var(--homeAccent) 16%, transparent);
    background: rgba(255, 255, 255, 0.72);
}

.wfDeck__caption {
    display: flex;
    align-items: baseline;
    gap: 12px;
    min-width: 0;
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.3;
    text-align: left;
}

.wfDeck__count {
    flex: none;
    color: color-mix(in srgb, var(--wf-ink) 45%, transparent);
    font-family: var(--font-meta, ui-monospace, monospace);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
}

.wfDeck__count b {
    font-weight: 400;
    color: color-mix(in srgb, var(--homeAccent) 80%, var(--wf-ink));
}

.wfDeck__name {
    min-width: 0;
    overflow: hidden;
    color: var(--wf-ink);
    font-weight: 600;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.wfDeck__controls {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--space-2, 8px);
}

/* style.css's `.mainHome :not(a)` repaints every border with !important;
   keep the carousel buttons' dark ring. */
.wfDeck .cs-carousel__prev,
.wfDeck .cs-carousel__next,
.wfDeck .wfDeck__toggle {
    border-color: var(--frgd) !important;
}

/* The controls only work with the script. */
.wfDeck:not(.is-ready) .wfDeck__controls {
    visibility: hidden;
}

/* Prev/next are the site's .cs-carousel__prev/__next (style.css); the pause
   toggle has no equivalent there, so it copies their look. */
.wfDeck__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    min-height: 36px;
    margin: 0;
    padding: 0;
    border: 2px solid var(--frgd) !important;
    border-radius: 50%;
    background: var(--action);
    color: var(--frgd);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition:
        transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1),
        box-shadow 0.25s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.wfDeck__toggle:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.6);
    transform: scale(1.04);
}

.wfDeck__toggle:active {
    transform: scale(0.96);
}

.wfDeck__toggle:focus-visible {
    outline: 2px solid var(--frgd);
    outline-offset: 2px;
}

.wfDeck__toggle svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

.wfDeck__icon--play,
.wfDeck.is-stopped .wfDeck__icon--pause {
    display: none;
}

.wfDeck.is-stopped .wfDeck__icon--play {
    display: block;
}

@media (prefers-reduced-motion: reduce) {
    .wfDeck__slide,
    .wfDeck__sheet,
    .wfDeck__sheet::after {
        transition: none;
    }

    /* Nothing moves on its own, so there is nothing to pause. */
    .wfDeck__toggle {
        display: none;
    }
}

/* --- Full-size viewer for a component definition --------------------------
   Opens in place over the board (ds-specs.js), exactly its size: name and
   close on top, the spec in the middle, the case-study link and previous/next
   below. The board stays visible, blurred, around it. */
.dsViewer {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    background: color-mix(in srgb, var(--homeAccent) 8%, rgba(255, 255, 255, 0.82));
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--frgd, #050038);
    line-height: 1.3;
    text-align: left;
    animation: dsViewerIn 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

.dsViewer[hidden] {
    display: none;
}

/* Focus lands on the viewer itself when it opens; the ring is for its controls. */
.dsViewer:focus {
    outline: none;
}

.dsSpecs.is-viewing .dsSpecs__actions {
    visibility: hidden;
}

@keyframes dsViewerIn {
    from { opacity: 0; transform: scale(0.98); }
    to   { opacity: 1; transform: none; }
}

.dsViewer__head,
.dsViewer__foot {
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px 10px 16px;
}

.dsViewer__foot {
    justify-content: space-between;
}

.dsViewer .dsViewer__count,
.dsViewer .dsViewer__title {
    margin: 0;
    padding: 0;
    text-align: left;
    hyphens: none;
}

.dsViewer .dsViewer__count {
    flex: none;
    color: rgba(5, 0, 56, 0.45);
    font-family: var(--font-meta, ui-monospace, monospace);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
}

.dsViewer__count b {
    font-weight: 400;
    color: var(--homeAccent);
}

.dsViewer .dsViewer__title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    font-family: "Bricolage Grotesque", "Bricolage Grotesque Fallback", "Bricolage Grotesque Fallback R", sans-serif;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* A size container, so the sheet can fit the spec to whatever room is left
   between the bars (100cqw by 100cqh) at its own aspect ratio. */
.dsViewer__figure {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    place-items: center;
    padding: 0 16px;
    container-type: size;
}

/* The sheet takes the full image's shape before it arrives, painted with the
   spec's low-res cell from the board sprite; the full image fades in on top. */
.dsViewer__sheet {
    position: relative;
    aspect-ratio: var(--w) / var(--h);
    width: min(100cqw, calc(100cqh * var(--w) / var(--h)), calc(var(--w) * 1px));
    overflow: hidden;
    background-color: #fff;
    background-repeat: no-repeat;
    border-radius: 8px;
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--homeAccent) 18%, transparent),
        0 12px 28px -14px rgba(40, 10, 90, 0.35);
}

.dsViewer__sheet img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    margin: 0;
}

.dsViewer__sheet img:not(.is-loaded) {
    opacity: 0;
}

.dsViewer__sheet img.is-loaded {
    transition: opacity 0.3s ease;
}

/* Same look as the card's own "Read case study" (style.css, .readMoreTop). */
body.home #main-content .cs-tldr--home .dsViewer a.dsViewer__case {
    color: color-mix(in srgb, var(--homeAccent) 72%, var(--frgd, #050038)) !important;
    text-decoration-color: color-mix(in srgb, var(--homeAccent) 55%, currentColor);
}

.dsViewer__nav {
    display: flex;
    gap: var(--space-2, 8px);
    margin-left: auto;
}

/* Close copies the carousel buttons, like the deck's pause toggle. */
.dsViewer__close {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin: 0;
    padding: 0;
    border: 2px solid var(--frgd, #050038);
    border-radius: 50%;
    background: var(--action);
    color: var(--frgd, #050038);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition:
        transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1),
        box-shadow 0.25s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.dsViewer__close:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.6);
    transform: scale(1.04);
}

.dsViewer__close:focus-visible {
    outline: 2px solid var(--frgd, #050038);
    outline-offset: 2px;
}

.dsViewer__close svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

/* Keep the dark ring against .mainHome's border-color override (see .wfDeck). */
.dsViewer .dsViewer__close,
.dsViewer .cs-carousel__prev,
.dsViewer .cs-carousel__next {
    border-color: var(--frgd, #050038) !important;
}

@media (prefers-reduced-motion: reduce) {
    .dsViewer {
        animation: none;
    }
}

/* --- Phones: the featured cards, cut down to a glance ---------------------
   Up to 768px the abstract card pile is hidden (craft-cards.css) and these
   four cards stand in for it, each reduced to who and when, the claim, the
   visual, the first lines of the problem and of what we did, and one link.
   The figures, the meta rows and "Show more" are left to the case study.
   The visual is a picture here, not a control: its buttons are hidden and it
   takes no taps, so the whole card is one target that opens the case study
   (the link's ::before covers the card, padding included). */
.topProjectsStack__more {
    display: none;
}

@media only screen and (max-width: 768px) {
    /* The logo strip now sits between the heading and the cards. */
    .homepage .orgCarousel {
        margin-bottom: 24px;
    }

    .topProjectsStack:not(.topProjectsStack--craft) {
        --mini-pad: 16px;
        gap: 40px;
    }

    .topProjectsStack .topProject {
        padding: var(--mini-pad);
    }

    /* One card scrolls into view at a time here, so the stagger that
       section-appear.js gives siblings would only hold each card back. */
    .topProjectsStack .topProject.section-appear.is-appeared {
        transition-delay: 0s;
    }

    /* Its own stacking context, so the link's cover (below) can sit above
       everything in the card without rising over anything outside it. */
    .topProject .cs-tldr--home {
        --home-gap: 16px;
        isolation: isolate;
    }

    .topProject .cs-tldr--home .cs-tldr__header {
        gap: 10px;
    }

    .topProject .cs-tldr--home .cs-tldr__header .topLogo {
        max-height: 28px;
    }

    /* Out, whatever state "Show more" left the card in on a wider screen. */
    .topProject .cs-tldr--home > .cs-tldr__figures,
    .topProject .cs-tldr--home > .cs-tldr__figuresNote,
    .topProject .cs-tldr--home > .cs-tldr__meta,
    .topProject .cs-tldr--home .cs-tldr__toggle,
    .topProject .cs-tldr--home .wfDeck__bar,
    .topProject .cs-tldr--home .dsSpecs__actions,
    .topProject .cs-tldr--home .dsViewer {
        display: none;
    }

    .topProject .cs-tldr--home .cs-tldr__visual {
        border-radius: 10px;
        box-shadow: none;
        pointer-events: none;
    }

    /* Knowledge-base loop: drawn at its wide size (record beside the chat)
       and scaled to the card, like the AI Native demo, rather than letting
       the frame restack itself for a narrow screen. */
    .topProject .LatestDemo--kb {
        aspect-ratio: 16 / 10;
    }

    .topProject .LatestDemo--kb iframe {
        position: absolute;
        top: 0;
        left: 0;
        width: 720px;
        height: 450px;
        transform: scale(calc(100cqw / 720px));
        transform-origin: top left;
    }

    /* A taste of the write-up: three lines each of the problem and of what
       we did. The case study has the rest, a tap away. */
    .topProject .cs-tldr--home > .cs-tldr__pair {
        display: grid;
        gap: 14px 24px;
    }

    .topProject .cs-tldr--home .cs-tldr__pair > div {
        padding-top: 10px;
        border-top-width: 1px;
    }

    .topProject .cs-tldr--home .cs-tldr__pair dt {
        margin-bottom: 4px;
    }

    .topProject .cs-tldr--home .cs-tldr__pair dd {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 3;
        line-clamp: 3;
        overflow: hidden;
        font-size: 0.9375rem;
        line-height: 1.5;
    }

    /* z-index: the site gives paragraphs z-index 2, which takes effect on the
       claim and the period because they are flex items; without this they sat
       on top of the cover and a tap on the headline did nothing. */
    body.home .topProject .cs-tldr--home .readMoreTop a.craftCard__link::before {
        content: "";
        position: absolute;
        inset: calc(var(--mini-pad) * -1);
        z-index: 3;
        border-radius: 12px;
    }

    /* The three case studies that only the pile showed are one tap away. */
    .topProjectsStack__more {
        --craftAccent: var(--frgd, #050038);
        display: block;
        margin: 8px 0 0;
        text-align: center;
    }

    body.home #main-content .topProjectsStack__more a.craftCard__link {
        margin: 0 !important;
    }
}

/* With motion off the logo strip stops scrolling and wraps into a wall of 32
   logos, about a screen tall on a phone, so there the cards go first. This is
   the only case where the visual order leaves the source order (the keyboard
   still reaches the logos first); the moving strip stays where the source
   puts it. */
@media only screen and (max-width: 768px) and (prefers-reduced-motion: reduce) {
    .homepage .orgCarousel {
        order: 1;
        margin-bottom: 48px;
    }

    .mainHome .borderWrapper > .colleaguesContainer {
        order: 2;
    }

    .mainHome .borderWrapper > #movingBanner {
        order: 3;
    }
}
