* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --bg: #ffffff;
    --text: #000000;
    --accent: #ff6b6b;
    --light-gray: #f5f5f5;
    --border: #e0e0e0;
    --wine: #6b0d1f;
    --blush: #f4c2c2;
    --ice: #dce8f1;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0a0a0a;
        --text: #ffffff;
        --light-gray: #1a1a1a;
        --border: #333333;
    }
}

html {
    scroll-behavior: smooth;
}

/* Newsreader Light = editorial voice. Azeret Mono = functional voice (small UI, labels, metadata). */
:root {
    --font-main: 'Newsreader', Georgia, serif;
    --font-mono: 'Azeret Mono', ui-monospace, Menlo, monospace;
}

button {
    font: inherit;
    border: none;
    cursor: pointer;
}

body {
    font-family: var(--font-main);
    font-weight: 300;
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    transition: background-color 0.3s, color 0.3s;
}

.intro {
    height: 105vh;
    height: 105dvh;
    background: var(--wine);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--blush);
    --logo-w: min(28vmin, 252px);
}

.intro-logo {
    width: var(--logo-w);
    height: auto;
    overflow: visible;
    /* 3vh above the screen's centre; the extra 2.5vh offsets the red running 5vh past the fold */
    translate: 0 -5.5vh;
}

/* Only the swirl turns, around its own centre (in SVG units); the label stays still */
.intro-mark {
    transform-box: view-box;
    transform-origin: 112.8px 114.62px;
    animation: spin 38s linear infinite;
}

/* Scaled from its top-centre, so it stays centred and keeps its distance from the swirl */
.intro-label {
    transform-box: fill-box;
    transform-origin: 50% 0;
    scale: 0.9;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

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

/* Navigation */
/* Pinned to the top and hidden over the red; fades in as the white page arrives (see script) */
nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    backdrop-filter: blur(10px);
    background: rgba(255, 255, 255, 0.8);
    border-bottom: 1px solid var(--border);
    opacity: 0;
    pointer-events: none;
}

@media (prefers-color-scheme: dark) {
    nav {
        background: rgba(10, 10, 10, 0.8);
    }
}

nav .container {
    /* Same side margins as the statement (section 2rem + container 2rem), so the links end where the text does */
    position: relative;
    max-width: none;
    padding: 1rem 4rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* Taken out of the layout and centred, so it never adds height to the bar */
.logo {
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    line-height: 0;
    color: var(--wine);
}

.logo svg {
    height: 30px;
    width: auto;
}

nav a.logo::after {
    display: none;
}

nav ul {
    list-style: none;
    display: flex;
    gap: 2rem;
    margin-right: 5px;
}

nav a {
    text-decoration: none;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    transition: color 0.3s;
    position: relative;
}

nav a::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 0;
    width: 0;
    height: 2px;
    background: var(--accent);
    transition: width 0.3s;
}

nav a:hover::after {
    width: 100%;
}

/* Container */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 2rem;
}

.cta {
    display: inline-block;
    padding: 0.9rem 2rem;
    background: var(--accent);
    color: white;
    text-decoration: none;
    border-radius: 4px;
    transition: all 0.3s;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.cta:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(255, 107, 107, 0.3);
}

/* Sections */
section {
    padding: 6rem 2rem;
    opacity: 0;
    animation: fadeIn 0.8s ease-out forwards;
}

section:nth-of-type(2) { animation-delay: 0.2s; }
section:nth-of-type(3) { animation-delay: 0.4s; }
section:nth-of-type(4) { animation-delay: 0.6s; }

h2 {
    font-family: var(--font-mono);
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 200;
    line-height: 1.1;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 3rem;
    text-align: center;
}

/* Statement */
.statement .container {
    max-width: none;
}

.statement p {
    font-family: var(--font-main);
    font-size: clamp(1.764rem, 4.586vw, 4.939rem);
    font-weight: 300;
    line-height: 1.02;
    letter-spacing: -0.02em;
}

.statement p + p {
    margin-top: 0.5em;
}

/* Supporting paragraph: 66% of the statement size, with more air around it. It runs no further right
   than 80% across the middle (Spazivo) image: that image is centred on the screen, so its 80% point
   is 50vw + 0.3 × image width, where image width = 2/3 of the image height the panel allows */
.statement p.statement-narrow,
.statement p.statement-small {
    max-width: calc(50vw + 0.2 * min(100vh - var(--nav-h, 59px) - 8.5rem - 26px, (100vw - 16rem) / 2) - 4rem - 160px);
    text-wrap: pretty;
}

.statement p.statement-small {
    font-size: calc(clamp(1.764rem, 4.586vw, 4.939rem) * 0.7);
    line-height: 1.3;
    letter-spacing: -0.01em;
    margin-top: 3.5rem;
    text-wrap: pretty;
}

/* Ice panel: empty, slides in from the right; settles at the text's left margin and runs to the right edge */
section.ice {
    padding: calc(2rem + 21px) 0 6rem 4rem;
    overflow-x: clip;
    opacity: 1;
    animation: none;
}

.ice-panel {
    --ice-pad-x: 2rem;
    --ice-pad-y: 1.5rem;
    --ice-gap: 2rem;
    height: calc(100vh - var(--nav-h, 59px) - 1rem - 26px);
    /* Held just under the nav while the spacer below scrolls past, giving the slide-in more time */
    position: sticky;
    top: calc(var(--nav-h, 59px) + 8px);
    background: var(--ice);
    transform: translateX(110vw);
    will-change: transform;
    container-type: size;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ice-gap);
    padding: 0 var(--ice-pad-x);
}

/* Sized for three 2:3 images in a row: as tall as the panel allows, unless three wouldn't fit across
   (cq units measure the panel's content box, i.e. already inside its side padding) */
/* The panel starts at the text margin but runs to the screen edge, so its centre sits half a margin
   right of the screen's centre; shifting by that much centres the images on the screen */
/* Every item reserves the same caption space under its image, so the images stay aligned and
   image + caption together sit centred in the panel. The extra 4rem in the width limit keeps at
   least 2rem of blue left of the first image once the row is shifted to the screen's centre */
.ice-item {
    --cap: 4.5rem;
    --img-h: min(100cqh - 2 * var(--ice-pad-y) - var(--cap), (100cqw - 4rem - 2 * var(--ice-gap)) / 3 * 3 / 2);
    translate: -2rem 0;
    flex: none;
    position: relative;
    width: calc(var(--img-h) * 2 / 3);
    padding-bottom: var(--cap);
}

.ice-item img {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: cover;
}

.cap-name {
    font-weight: 500;
}

/* Each caption line is its own block so it can trail its image separately */
.cap-line {
    display: block;
    will-change: transform;
}

.ice-item figcaption {
    position: absolute;
    left: 0;
    bottom: 0;
    height: var(--cap);
    padding-top: 0.9rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.ice-spacer {
    height: 45vh;
}

/* Contact Section */
.contact-content {
    max-width: 600px;
    margin: 0 auto;
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    margin-top: 2rem;
}

.form-group {
    display: flex;
    flex-direction: column;
}

.form-group label {
    margin-bottom: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.form-group input,
.form-group textarea {
    padding: 0.75rem 1rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg);
    color: var(--text);
    font-family: inherit;
    font-size: 1rem;
    transition: border-color 0.3s;
}

.form-group input:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.form-group textarea {
    resize: vertical;
    min-height: 150px;
}

/* Footer */
footer {
    background: var(--light-gray);
    padding: 2rem;
    text-align: center;
    border-top: 1px solid var(--border);
}

footer p {
    opacity: 0.7;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* Animations */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Responsive */
@media (max-width: 768px) {
    nav .container {
        padding: 1rem 3.5rem;
        justify-content: space-between;
    }

    /* No room for three items on a phone: the wordmark stays, the centre swirl steps aside */
    .logo {
        display: none;
    }

    nav ul {
        gap: 1rem;
    }

    nav a {
        font-size: 0.75rem;
    }

    section {
        padding: 4rem 1.5rem;
    }

    section.ice {
        padding: calc(2rem + 21px) 0 4rem 3.5rem;
    }

    .ice-item {
        translate: -1.75rem 0;
    }

    h2 {
        margin-bottom: 2rem;
    }
}

/* Closing text with a second ice panel beside it: the panel starts a gap after the text column
   (which ends 80% across the Spazivo image) and runs to the screen edge, as tall as the first panel */
section.closing {
    overflow-x: clip;
}

.closing-row {
    /* Same sizing inputs as the project row above: the image height the first panel allows (--img-h)
       and the first panel's height (--panel-h) */
    --img-h: min(100vh - var(--nav-h, 59px) - 8.5rem - 26px, (100vw - 16rem) / 2);
    --panel-h: calc(100vh - var(--nav-h, 59px) - 1rem - 26px);
    display: flex;
    align-items: flex-start;
}

/* Pushed down by the image's distance from the frame's top, so "Good" lines up with the image */
.closing-text {
    margin-top: calc((var(--panel-h) - var(--img-h) - 4.5rem) / 2);
    flex: none;
    width: calc(50vw + 0.2 * min(100vh - var(--nav-h, 59px) - 8.5rem - 26px, (100vw - 16rem) / 2) - 4rem - 160px);
}

.closing-panel {
    /* The frame's extra shift to the right; the image and caption inside subtract it again so they
       stay lined up with Mora above */
    --frame-shift: -20px;
    position: relative;
    flex: 1;
    /* +160px: the text column beside it is 160px narrower; this keeps the frame's position
       governed by --frame-shift alone */
    margin-left: calc(4rem + var(--frame-shift) + 160px);
    margin-right: -4rem;
    /* Three caption lines, like the row above, so it's the same height as the first panel */
    height: var(--panel-h);
    background: var(--wine);
    transform: translateX(110vw);
    will-change: transform;
}

/* Sits exactly where Mora sits in the row above: same size, same distance from the panel's top, and
   the same position across the screen (Mora's left edge is 50vw + img-width/2 + gap; this panel starts at
   50vw + 0.2 × img-h + 4rem, so the offset inside the panel is img-h × 2/15 − 2rem) */
.closing-image {
    position: absolute;
    left: calc(var(--img-h) * 2 / 15 - 2rem - var(--frame-shift));
    top: calc((var(--panel-h) - var(--img-h) - 4.5rem) / 2);
    width: calc(var(--img-h) * 2 / 3);
    aspect-ratio: 2 / 3;
    object-fit: cover;
    display: block;
}

/* Styled like the project captions, placed under the image the same way
   (".statement" in the selector so the statement's big type doesn't override it) */
.statement .closing-caption {
    white-space: nowrap;
    font-weight: 300;
    color: #fff;
    position: absolute;
    left: calc(var(--img-h) * 2 / 15 - 2rem - var(--frame-shift));
    top: calc((var(--panel-h) - var(--img-h) - 4.5rem) / 2 + var(--img-h));
    padding-top: 0.9rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

@media (max-width: 768px) {
    .closing-panel {
        display: none;
    }
}

/* ---------- Project pages ---------- */

/* On project pages there's no red intro, so the nav is simply there */
body.project nav {
    opacity: 1;
    pointer-events: auto;
}

.project-page {
    padding: calc(var(--nav-h, 59px) + 4rem) 4rem 6rem;
}

.project-page .project-meta {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 1.5rem;
}

.project-page h1 {
    font-size: clamp(2.5rem, 6vw, 5.5rem);
    font-weight: 300;
    line-height: 1.02;
    letter-spacing: -0.02em;
    margin-bottom: 3rem;
}

.project-page img {
    display: block;
    width: min(100%, 560px);
    aspect-ratio: 2 / 3;
    object-fit: cover;
}

/* Header swirl: on a project page it slowly fades from wine red to that project's colour,
   set per page as --project-swirl on <body> */
.logo {
    transition: color 2.5s ease;
}

.logo.is-project {
    color: var(--project-swirl, var(--text));
}

/* Project cards link through to their pages */
.ice-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

/* Arriving via a section link (e.g. from a project page): no red intro, nav visible from the start */
html.skip-intro .intro {
    display: none;
}

html.skip-intro nav {
    opacity: 1;
    pointer-events: auto;
}

/* Services frame: the same ice-blue frame and grid as the project row. Each column takes exactly the
   space an image + its caption would: an image's width, from the image's top to the caption's end */
section.svc {
    padding: calc(2rem + 21px) 0 6rem 4rem;
    overflow-x: clip;
    opacity: 1;
    animation: none;
}

/* The two strips share one project frame's height: 48% + 4% gap + 48% */
section.svc:has(+ section.svc) {
    padding-bottom: 0;
}

section.svc + section.svc {
    padding-top: calc((100vh - var(--nav-h, 59px) - 1rem - 26px) * 0.04);
}

.svc-panel {
    --ice-pad-x: 2rem;
    --ice-pad-y: 1.5rem;
    --ice-gap: 2rem;
    /* 48% of the project frame's height */
    height: calc((100vh - var(--nav-h, 59px) - 1rem - 26px) * 0.48);
    background: var(--ice);
    container-type: size;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--ice-gap);
    padding: 0 var(--ice-pad-x);
    transform: translateX(110vw);
    will-change: transform;
}

.svc-item {
    /* Column widths come from the project row's image size (not this shorter strip), so the columns
       stay exactly under the images; the height is whatever the strip leaves inside its padding */
    --img-h: min(100vh - var(--nav-h, 59px) - 8.5rem - 26px, (100vw - 16rem) / 2);
    translate: -2rem 0;
    flex: none;
    width: calc(var(--img-h) * 2 / 3);
    height: calc(100cqh - 2 * var(--ice-pad-y));
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 300;
    line-height: 1.6;
    letter-spacing: 0.06em;
}

/* Styled like the project captions (small, uppercase; first line heavier). Title and tagline sit at the
   top, the list is pinned to the bottom of the column */
.svc-item {
    --col-w: calc(var(--img-h) * 2 / 3);
    display: flex;
    flex-direction: column;
}

.svc-item p {
    text-transform: uppercase;
}

.svc-item .svc-title + .svc-lead {
    margin-top: 0;
}

.svc-item .svc-list {
    margin-top: auto;
}

/* Spans the first two columns (two image widths plus the gap between them) */
.svc-item.svc-wide {
    width: calc(var(--img-h) * 4 / 3 + var(--ice-gap));
}

.svc-title,
.svc-list {
    text-transform: uppercase;
}

.svc-title {
    font-weight: 500;
}

/* "And after launch?": no frame, straight on the white under the services strip. Same grid (so it lines
   up with the first column), text spanning the first column plus ~14% of the second, list following
   closely instead of being pinned to the bottom */
.svc-plain .svc-panel {
    transform: none;
    background: transparent;
    height: auto;
    container-type: normal;
    align-items: flex-start;
    padding-top: calc(var(--ice-pad-y) + 20px);
}

.svc-plain .svc-item {
    height: auto;
}

.svc-plain .svc-wide p {
    max-width: calc(var(--img-h) * 2 / 3 * 1.14 + var(--ice-gap));
}

.svc-plain .svc-item .svc-list {
    margin-top: 1.6em;
}

@media (max-width: 768px) {
    section.svc {
        padding: calc(2rem + 21px) 0 4rem 3.5rem;
    }

    .svc-item {
        translate: -1.75rem 0;
    }
}


/* =====================================================================================
   Version 2: flat. Canvas background, Ink for all type, logo and rules, Azeret Mono
   everywhere, no frames or boxes, no animation — everything is simply in place.
   ===================================================================================== */

:root,
:root:not(.x) {
    --bg: #fafaf8;
    --text: #111111;
    --light-gray: transparent;
    --border: #111111;
    --accent: #111111;
    --font-main: 'Azeret Mono', ui-monospace, Menlo, monospace;
}

html,
body {
    background: var(--bg);
    color: var(--text);
}

/* Header: built by the entrance. Its line stays a construction line, just 25% darker than the others.
   Bar (background, line, links), swirl and wordmark each switch on as the entrance delivers them. */
nav,
nav:not(.docked) {
    background: transparent;
    backdrop-filter: none;
    border-bottom: none;
    opacity: 1;
    pointer-events: none;
}

nav ul,
nav .logo,
nav .wordmark {
    opacity: 0;
}

nav.bar-on,
nav:focus-within,
html.skip-intro nav,
body.project nav {
    pointer-events: auto;
}

/* the header's line: dotted like every construction line, starting at the screen's left edge like them */
nav::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: repeating-linear-gradient(to right,
        var(--construction-strong) 0 2px,
        transparent 2px 7px);
    visibility: hidden;
    pointer-events: none;
}

nav.bar-on::after,
html.skip-intro nav::after,
body.project nav::after {
    visibility: visible;
}

nav.filled,
html.skip-intro nav,
body.project nav {
    background: var(--bg);
}

nav.bar-on ul,
nav.logo-on .logo,
nav.name-on .wordmark,
nav:focus-within ul,
nav:focus-within .logo,
nav:focus-within .wordmark,
html.skip-intro nav ul,
html.skip-intro nav .logo,
html.skip-intro nav .wordmark,
body.project nav ul,
body.project nav .logo,
body.project nav .wordmark {
    opacity: 1;
}

.logo,
.logo.is-project {
    color: var(--text);
}

section {
    animation: none;
    opacity: 1;
}

/* Former frames: no colour, no movement, content stays where it was */
.ice-panel,
.closing-panel,
.svc-panel {
    background: transparent;
    transform: none;
}

.ice-panel {
    position: static;
}

.ice-item,
.svc-item,
.cap-line,
.closing-image,
.closing-caption {
    transform: none;
}

.statement .closing-caption {
    color: var(--text);
}

/* Form: plain ink lines instead of boxes */
.form-group input,
.form-group textarea {
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--text);
    border-radius: 0;
    padding-left: 0;
    padding-right: 0;
}

.cta,
.cta:hover {
    background: transparent;
    color: var(--text);
    border-radius: 0;
    border-bottom: 1px solid var(--text);
    padding: 0.9rem 0;
    transform: none;
    box-shadow: none;
}

footer {
    background: transparent;
    border-top: 1px solid var(--text);
}

/* Entrance: same as before (spinning S + wordmark, same timing), but off-white with a black mark */
.intro {
    background: var(--bg);
    color: var(--text);
}

/* Wordmark under the spinning S sits 7px lower than in version 1 (SVG units ≈ px at laptop size) */
.intro-label {
    translate: 0 7px;
}

/* No animation anywhere, except the intro's spinning swirl */
*:not(.intro-mark) {
    transition: none !important;
    animation: none !important;
}

/* ---------- Construction line (reusable) ----------
   A drafting-guide line: 1px, black at 40%, short square dashes (2px line / 5px gap).
   Use with a direction modifier, then position it where needed:
     <div class="construction-line construction-line--v"></div>  vertical
     <div class="construction-line construction-line--h"></div>  horizontal
   Override --cl-dash / --cl-gap / --cl-color on an instance to vary it. */
:root {
    --construction: rgba(0, 0, 0, 0.50);   /* a little darker */
}

.construction-line {
    --cl-color: var(--construction);
    --cl-dash: 2px;
    --cl-gap: 5px;
    pointer-events: none;
}

.construction-line--v {
    width: 1px;
    background: repeating-linear-gradient(to bottom,
        var(--cl-color) 0 var(--cl-dash),
        transparent var(--cl-dash) calc(var(--cl-dash) + var(--cl-gap)));
}

.construction-line--h {
    height: 1px;
    background: repeating-linear-gradient(to right,
        var(--cl-color) 0 var(--cl-dash),
        transparent var(--cl-dash) calc(var(--cl-dash) + var(--cl-gap)));
}

/* First placement: a full-height guide on the left text margin, the edge the statements,
   project images and service columns all start from (sits under the nav) */
.guide-margin-left {
    position: fixed;
    top: 0;
    bottom: 0;
    left: calc(4rem - 1px);
    z-index: 50;
}

@media (max-width: 768px) {
    .guide-margin-left {
        left: calc(3.5rem - 1px);
    }
}

/* ---------- Entrance: the mark being measured ----------
   Exactly one screen. The symbol sits on the exact centre (same size as before), slowly turning; two
   concentric dotted circles stay still around it. "SPILLED SODA" sits below it. Everything scales with
   the symbol's width (--symbol-w), keeping the proportions of the 105px brief: circles 170 / 280,
   gap 24. Ground rule: every line runs edge to edge (full width or full height), never stopping short. */
.intro,
:root .intro {
    --intro-h: 100vh;
    --symbol-w: min(28vmin, 252px);
    --u: calc(var(--symbol-w) / 105);
    --sym-half: calc(var(--symbol-w) * 229.2361 / 225.5995 / 2);
    --name-gap: calc(24 * var(--u));
    position: relative;
    display: block;
    height: var(--intro-h);
    overflow: hidden;
}

.intro-guide-v {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    translate: -0.5px 0;
}

.intro-guide-h {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    translate: 0 -0.5px;
}

.intro-circles {
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(300 * var(--u));
    height: calc(300 * var(--u));
    translate: -50% -50%;
    overflow: visible;
    fill: none;
    stroke: var(--construction);
    stroke-width: 1;
    stroke-dasharray: 2 5;
}

.intro-circles circle {
    vector-effect: non-scaling-stroke;
}

.intro-symbol {
    position: absolute;
    left: 50%;
    top: 50%;
    width: var(--symbol-w);
    height: auto;
    translate: -50% -50%;
    overflow: visible;
    color: var(--text);
}

/* Same size as the old wordmark (about 75% of the symbol's width) */
.intro-name {
    position: absolute;
    left: 50%;
    top: calc(50% + var(--sym-half) + var(--name-gap));
    translate: -50% 0;
    margin: 0;
    font-family: var(--font-mono);
    font-size: calc(var(--symbol-w) * 0.0859);
    font-weight: 300;
    line-height: 1;
    letter-spacing: 0.08em;
    /* balances the trailing letter-spacing, so the letters themselves are centred */
    padding-left: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text);
}

/* Guides marking SPILLED SODA's bounds, edge to edge like every line: top and bottom across the full
   width, left and right down the full height of the entrance */
.name-guide {
    position: absolute;
    display: block;
}

.name-guide-top,
.name-guide-bottom {
    left: 50%;
    width: 100vw;
    translate: -50% 0;
}

/* Top and bottom lines sit half as far from the letters as the square's side lines do (the name stays
   centred between them). All in symbol widths (W), measured for
   Azeret Mono Light at 0.0859 W: letters are 0.7457 W wide → side gap (1 − 0.7457) / 2 = 0.1272 W;
   cap tops sit 0.0127 W below the line-box top and the caps are 0.0620 W tall. */
.name-guide-top {
    top: calc(var(--symbol-w) * (0.0127 - 0.0636) - 0.5px);
}

.name-guide-bottom {
    top: calc(var(--symbol-w) * (0.0127 + 0.0620 + 0.0636) - 0.5px);
}

.name-guide-left,
.name-guide-right {
    top: calc(-1 * (var(--intro-h) / 2 + var(--sym-half) + var(--name-gap)));
    height: var(--intro-h);
}

.name-guide-left {
    left: 0;
}

/* inset by the trailing letter-spacing, so it sits on the last letter's edge */
.name-guide-right {
    right: 0.08em;
}

/* Square framing the symbol's original image (its unrotated bounds), each side edge to edge.
   The symbol turns inside it, so its tips occasionally cross the lines. */
.symbol-guide {
    position: absolute;
}

.symbol-guide-top,
.symbol-guide-bottom {
    left: 0;
    right: 0;
}

.symbol-guide-top {
    top: calc(50% - var(--sym-half));
}

.symbol-guide-bottom {
    top: calc(50% + var(--sym-half));
    translate: 0 -1px;
}

.symbol-guide-left,
.symbol-guide-right {
    top: 0;
    bottom: 0;
}

.symbol-guide-left {
    left: calc(50% - var(--symbol-w) / 2);
}

.symbol-guide-right {
    left: calc(50% + var(--symbol-w) / 2);
    translate: -1px 0;
}

/* Entrance holds in place for 2.2 screens of scrolling while it builds the header (see script) */
.intro,
:root .intro {
    /* 2.2 screens of hold: swirl lands at 1.6, name and links at 2 while the lines build the statement's
       frame; the text appears there, the header line turns solid at 2.1 and the page moves on at 2.2 */
    height: calc(var(--intro-h) * 3.2);
    overflow: visible;
}

.intro-stage {
    position: sticky;
    top: 0;
    height: var(--intro-h);
    overflow: hidden;
}

/* The swirl's spin is driven by script now (so it can settle as it reaches the header) */
.intro-mark {
    animation: none;
}

.intro-name-text {
    display: inline-block;
    transform-origin: 0 0;
}

/* Header swirl nudged up so it sits centred between SPILLED SODA's two guide lines as the entrance ends */
nav .logo svg {
    translate: 0 -3.6px;
}

/* ---------- Statement in its frame ----------
   Smaller type. The statement overlaps the entrance's last screen, so it scrolls up into the frame the entrance's
   lines have built, arriving as the hold ends (then the entrance is removed and the overlap with it). */
#statement {
    position: relative;
    z-index: 1;
    /* overlapping the entrance's last screen, and 250px more, so it comes in that much earlier (PHIL_EARLY) */
    margin-top: calc(-1 * var(--intro-h, 100vh) - 250px);
    background: transparent;
    overflow-x: clip;
    --sf-gap: 16px;
    /* lower, so the frame's top line sits well clear of the header */
    padding-top: 8rem;
    box-sizing: border-box;
}

html.intro-gone #statement,
html.skip-intro #statement {
    margin-top: 0;
}

#statement p {
    font-size: clamp(1.25rem, 2.6vw, 2.8rem);
    font-weight: 200;
    line-height: 1.25;
}

/* The frame keeps the same visible distance to the letters on all four sides. Measured for Azeret Mono Light
   at line-height 1.1: cap tops sit 0.1716em below the first line box, the baseline 0.2183em above the last
   one's bottom, and the letters' side bearing adds 0.0723em at the left, so top and bottom get that too. */
.statement-frame {
    position: relative;
    font-size: clamp(1.25rem, 2.6vw, 2.8rem);
    --sf-bearing: 0.0723em;
}

.sf-line {
    position: absolute;
}

/* horizontals start at the screen's left edge (section 2rem + container 2rem), like the entrance's lines */
.sf-top,
.sf-bottom {
    left: -4rem;
    right: -4rem;
}

.sf-top {
    top: calc(0.1716em - var(--sf-bearing) - var(--sf-gap));
}

.sf-bottom {
    bottom: calc(0.2183em - var(--sf-bearing) - var(--sf-gap));
}

/* verticals run the statement section's full height (at least a screen), just outside the text margins
   (section 2rem + container 2rem) */
.sf-left,
.sf-right {
    top: 0;
    bottom: 0;
}

.sf-left {
    left: calc(4rem - var(--sf-gap));
}

.sf-right {
    right: calc(4rem - var(--sf-gap));
    translate: 1px 0;
}

/* the statement's frame lines only mark where the frame goes: the lines shown are the layer's (below) */
.sf-line {
    visibility: hidden;
}

/* Wider screens: the right border sits a tad (0.75rem) left of WORK in the header, and the text column ends one
   gap before it, so the distance stays the same on all four sides */
@media (min-width: 769px) {
    .sf-right {
        right: auto;
        left: calc(var(--work-left, calc(100vw - 4rem)) - 0.75rem);
        translate: 0 0;
    }

    #statement .statement-frame {
        max-width: calc(var(--work-left, calc(100vw - 4rem)) - 0.75rem - var(--sf-gap) - 4rem);
    }

    /* the column is narrower than the screen now, so the top and bottom lines take the screen's full width */
    .sf-top,
    .sf-bottom {
        right: auto;
        width: 100vw;
    }
}

@media (max-width: 768px) {
    #statement {
        --sf-gap: 16px;
    }

    /* narrower text margins on phones (3.5rem) */
    .sf-top,
    .sf-bottom {
        left: -3.5rem;
        right: -3.5rem;
    }

    .sf-left {
        left: calc(3.5rem - var(--sf-gap));
    }

    .sf-right {
        right: calc(3.5rem - var(--sf-gap));
    }
}

/* The statement's reveal once its frame exists: almost immediate, just a fade and a 10px rise.
   (The id outranks the sitewide "no transitions" rule.) */
#statement .statement-frame > p {
    transition: opacity 250ms ease-out, transform 250ms ease-out !important;
}

#statement.awaiting .statement-frame > p {
    opacity: 0;
    transform: translateY(10px);
}

@media (prefers-reduced-motion: reduce) {
    #statement.awaiting .statement-frame > p {
        transform: none;
    }
}

/* ---------- The lines after the entrance ----------
   A layer that stays on screen; the script places each line (verticals full height, horizontals full width). */
.frame-layer {
    position: fixed;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    visibility: hidden;
}

.frame-layer.on {
    visibility: visible;
}

.fl {
    position: absolute;
    top: 0;
    left: 0;
}

/* the horizontals' container sits on the page (top-left of the document) rather than on the screen */
.frame-layer-h {
    position: absolute;
    inset: 0 0 auto 0;
    height: 0;
}

.frame-layer-h .fl {
    position: fixed;
}

.fl-v {
    bottom: 0;
}

.fl-h {
    right: 0;
}

/* captions sit one frame gap (16px) below the line under the images, so every part keeps the same distance */
.ice-item {
    --cap: 5.3rem;
}

.ice-item figcaption {
    padding-top: 1.7rem;
}

/* Work: a tad smaller (90%), the row aligned right with CONTACT in the header (the panel's right padding matches
   the header's side margin), so the space on the left stays larger than on the right */
/* (--contact-gap: from the screen's right edge to CONTACT's last letter, measured by the script) */
.ice-panel {
    justify-content: flex-end;
    padding-right: var(--contact-gap, 4rem);
}

/* 90% of the previous size, which was measured on the old, centred panel (screen minus 8rem of margins); shared
   with the services below so their columns stay exactly under the projects */
:root {
    --work-img-h: min(100vh - var(--nav-h, 59px) - 1rem - 26px - 3rem - 5.3rem, 0.9 * (100vw - 12rem - 4rem) / 2);
}

.ice-item {
    --img-h: var(--work-img-h);
    translate: 0 0;
}

.svc-panel {
    justify-content: flex-end;
    padding-right: var(--contact-gap, 4rem);
}

.svc-item {
    --img-h: var(--work-img-h);
    translate: 0 0;
}

@media (max-width: 768px) {
    .ice-panel {
        padding-right: var(--contact-gap, 3.5rem);
    }

    :root {
        --work-img-h: min(100vh - var(--nav-h, 59px) - 1rem - 26px - 3rem - 5.3rem, 0.9 * (100vw - 11.5rem - 4rem) / 2);
    }

    .ice-item,
    .svc-item {
        translate: 0 0;
    }

    .svc-panel {
        padding-right: var(--contact-gap, 3.5rem);
    }
}

/* Studio: "Good ideas have a way of spilling over." on its own and large (1.6x the old statement size), framed by
   the construction lines with its right border slightly after Spazivo's caption "Brand Identity / Art Direction" */
.statement p.statement-narrow {
    font-size: calc(clamp(1.764rem, 4.586vw, 4.939rem) * 1.6);
    max-width: none;
}

/* (--closing-w: up to one frame gap before its right border; set by the script) */
.closing-text {
    width: var(--closing-w, calc(100vw - 8rem));
}

@media (max-width: 768px) {
    .closing-text {
        width: 100%;
    }
}

/* The line under it, set like the service lists (Azeret Mono Light, uppercase, slightly spaced), sized by the
   script to run the column's full width */
.statement p.statement-tagline {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 300;
    line-height: 1.6;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-top: 2rem;
    white-space: nowrap;
}

/* Services: more room after the studio line so the lines flow over organically, then the heading "Here's how",
   set exactly like "We make yours hard to forget.", starting where the first column (01, under Bobbie) starts; the columns are
   2 x --work-img-h wide in all plus two gaps, ending where CONTACT does */
section.svc:not(.svc-plain) {
    margin-top: 15vh;
}

.svc-heading {
    /* identical to "We make yours hard to forget." (its size is copied by the script) */
    font-family: var(--font-mono);
    font-size: clamp(2rem, 5vw, 3rem);
    font-weight: 300;
    line-height: 1.6;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: left;
    /* its own moment: about a screen of room before the columns, so its frame can form, hold and move on like
       every other frame's */
    margin: 0 0 calc(85vh - 3rem) calc(100% - var(--contact-gap, 4rem) - 2 * var(--work-img-h) - 2 * 2rem);
}

/* Services columns: the list follows its lead closely (as in "And after launch?") instead of being pinned to the
   bottom, so the strip is only as tall as its text */
section.svc:not(.svc-plain) .svc-panel {
    height: auto;
    container-type: normal;
    align-items: flex-start;
    padding-top: var(--ice-pad-y);
    padding-bottom: var(--ice-pad-y);
}

section.svc:not(.svc-plain) .svc-item {
    height: auto;
}

section.svc:not(.svc-plain) .svc-item .svc-list {
    margin-top: 83px;
}

/* "Here's how": its letters (not just its box) start where 01's do */
.svc-heading {
    text-indent: calc(-0.0723em + 0.054rem);
}

/* The swirl takes the colour of the page it's on: wine red on the home page (entrance and header), blush on Behind
   the Label, and each project's own colour on its page */
:root {
    --swirl: var(--wine, #6b0d1f);
}

body.page-label {
    --swirl: var(--blush);
}

body.page-bobbie {
    --swirl: #000000;
}

body.page-spazivo {
    --swirl: #7D8F9A;   /* a dirty, muted blue (Spazivo's own #A9BEC9, greyed down) */
}

body.page-lucky {
    --swirl: #D5E6EE;   /* Lucky Duck's sky blue */
}

.intro-symbol,
.logo,
.logo.is-project,
body.project nav .logo {
    color: var(--swirl);
}

/* On Behind the Label and the project pages the swirl arrives in wine red, waits a second, then slowly turns into the
   page's colour (outranks the sitewide "no animation" rule) */
@keyframes swirl-to-page {
    from { color: var(--wine, #6b0d1f); }
    to { color: var(--swirl); }
}

body.project nav .logo {
    animation: swirl-to-page 2.5s ease 1s both !important;
}

/* "And after launch?" and contact: further down, with enough room before each that every frame forms, holds and
   moves on for as long as the others do */
section.svc.svc-plain {
    margin-top: 55vh;
}

#contact {
    margin-top: 18vh;
    /* a little room before the footer */
    padding-bottom: calc(6rem + 10vh);
}

/* "And after launch?": its text as wide as one column, like 01, so it shares 01's right border */
.svc-plain .svc-wide p {
    max-width: calc(var(--img-h) * 2 / 3);
}

/* The label, back after "And after launch?": the photo at the projects' size, exactly where Spazivo sits (on the
   right-aligned grid: Mora ends where CONTACT does, columns 2/3 x --work-img-h wide, gaps 2rem), its caption set
   like the project captions */
.label-section {
    padding: 20vh 0 0 4rem;   /* (its distance is set by the script) */
    overflow-x: clip;
}

.label-section .closing-panel {
    position: relative;
    flex: none;
    width: calc(var(--work-img-h) * 2 / 3);
    height: auto;
    /* exactly where Spazivo sits (the middle column: 100% - CONTACT's gap - two columns - one gap) */
    margin: 0 0 0 calc(100% - var(--contact-gap, 4rem) - var(--work-img-h) * 4 / 3 - 2rem);
    background: transparent;
    transform: none;
}

.label-section .closing-image {
    position: static;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: cover;
    display: block;
}

.label-section .closing-caption {
    position: static;
    white-space: nowrap;
    margin: 0;
    padding-top: 1.7rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 300;
    line-height: 1.6;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
}

@media (max-width: 768px) {
    .label-section {
        padding-left: 3.5rem;
    }
}

/* Header and footer lines: construction lines 25% darker than the rest (40% -> 65% black) */
:root {
    --construction-strong: rgba(0, 0, 0, 0.65);
}

/* Footer: no solid line any more; its line is a construction line on its top edge, turning darker (like the
   header's) half a second after the bottom of the page is reached (on project pages it's simply dark) */
footer {
    position: relative;
    border-top: none;
}

footer::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: repeating-linear-gradient(to right,
        var(--footer-line, var(--construction)) 0 2px,
        transparent 2px 7px);
}

footer.line-on::before,
body.project footer::before {
    --footer-line: var(--construction-strong);
}

/* Services and "And after launch?" text: 0.9rem, then 15% larger -> 1.035rem (same columns, so the frame's side
   borders stay) */
.svc-item {
    font-size: 1.035rem;
}

/* Contact: one button across the form's width, the question on its left and "Spill anyway. →" on its right; no box,
   just brackets at its two ends, like the two halves of a rectangle; set at the size of the form's labels */
.form-spill {
    position: relative;
    /* reaching 1rem past the form on either side: its brackets sit where the writing frames (and the construction
       lines) do, and its text lines up with the labels */
    margin: 1rem -1rem 0;
    width: calc(100% + 2rem);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.8rem 1rem;
    border: none;
    border-radius: 0;
    background: none;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
}

.form-spill::before,
.form-spill::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0.6rem;
    border: 1px solid var(--text);
    pointer-events: none;
}

.form-spill::before {
    left: 0;
    border-right: none;
}

.form-spill::after {
    right: 0;
    border-left: none;
}

.form-spill-question {
    font-weight: 300;
}

.form-spill-action {
    flex: none;
    font-weight: 500;
}

/* Hovering "Spill anyway." (not the question): the construction lines close around it (see script) and the arrow
   goes */
.form-spill-action:hover .form-spill-arrow {
    display: none;
}


/* "What's on your mind?": one line tall, like Name and Email (same box, same distance from label to line), growing
   downwards as more is written (the script sets its height) */
.form-group textarea {
    min-height: 0;
    resize: none;
    overflow: hidden;
    line-height: normal;
    box-sizing: border-box;
}

/* Footer: as tall as the header (its height is shared by the script), its line of text centred in it */
footer {
    box-sizing: border-box;
    height: var(--header-h, 57.6px);
    padding: 0 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

footer p {
    margin: 0;
}

/* Contact on the grid: "Have something in mind? Spill." where Bobbie sits (one column), set right and as large as
   the column allows; the form beside it where Spazivo and Mora sit (two columns and the gap between them) */
#contact {
    padding-left: 4rem;
    padding-right: 0;
}

#contact .container {
    max-width: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: flex-start;
}

#contact h2 {
    flex: none;
    /* one column wide, less 14px of breathing room before the line in the gutter (so "MIND?" and that line don't
       tangle); its left edge stays at the column's */
    width: calc(var(--work-img-h) * 2 / 3 - 14px);
    margin: 0 14px 0 auto;
    text-align: right;
    /* as large as the column allows (sized by the script), with slightly tighter spacing to allow more */
    font-size: 3.5rem;
    letter-spacing: -0.01em;
    line-height: 1.25;
    overflow-wrap: normal;
    word-break: keep-all;
}

#contact .contact-content {
    flex: none;
    width: calc(var(--work-img-h) * 4 / 3 + 2rem);
    max-width: none;
    margin: 0 var(--contact-gap, 4rem) 0 2rem;
}

#contact .contact-form {
    margin-top: 0;
}

@media (max-width: 768px) {
    #contact {
        padding-left: 3.5rem;
    }

    #contact .container {
        flex-direction: column;
    }

    #contact h2,
    #contact .contact-content {
        width: auto;
        margin-left: 0;
        margin-right: var(--contact-gap, 3.5rem);
        font-size: clamp(2rem, 8vw, 3rem);
    }

    #contact .contact-content {
        font-size: 1rem;
    }
}


@media (max-width: 768px) {
    /* the label shows on phones too (an old rule hid that panel there) */
    .label-section .closing-panel {
        display: block;
    }

}

/* the contact form slides in from the right (moved by the script); the section clips it so the page never widens */
#contact {
    overflow-x: clip;
}

/* "Spill." on its own line, sized and placed by the script */
.contact-spill {
    display: block;
}

/* no brackets around the question and "Spill anyway." any more */
.form-spill::before,
.form-spill::after {
    display: none;
}

/* the lists under the services (and after launch) a bit smaller than the titles: 0.75rem (12px); titles and
   leads stay, and the lists sit further from them */
.svc-item .svc-list {
    font-size: 0.8625rem;   /* 0.75rem + 15% */
    /* every item after a plus (each item kept together on its line) */
    text-align: left;
}

section.svc .svc-item .svc-list,
.svc-plain .svc-item .svc-list {
    margin-top: 83px;
}

/* the footer is opaque, like the header: the construction lines run up to it, not through it */
footer {
    background: var(--bg);
    z-index: 3;
}

/* The form's own notes (instead of the browser's pop-ups): floating over the field's line, set right so they never
   meet what's typed, bigger and thinner than the labels (ExtraLight) and in the swirl's wine red, so they read as
   something added; laid over the field, they never make the form (or its frame) taller */
.form-hint {
    position: absolute;
    right: 0;
    bottom: 0.55rem;
    margin: 0;
    white-space: nowrap;
    pointer-events: none;
    font-family: var(--font-mono);
    font-size: 1.125rem;
    font-weight: 200;
    line-height: 1.2;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--wine, #6b0d1f);
}

.form-hint:empty {
    display: none;
}

/* The form holds its own beside the large headline: labels +1px (still Light), typed text +1px, and the send
   line +1px */
#contact .form-group label {
    font-size: 0.8125rem;
    font-weight: 300;
}

#contact .form-group input,
#contact .form-group textarea {
    font-size: 1.0625rem;
}

#contact .form-spill {
    font-size: 0.8125rem;
}

/* each field is the reference for its note */
#contact .form-group {
    position: relative;
}

/* Once sent: the form goes and the thanks stays in its space (kept at the form's size), centred there and sized by
   the script to run exactly across it; the heading stays */
#contact.sent .contact-form {
    display: none;
}

#contact.sent .contact-content {
    display: flex;
    align-items: center;
}

.contact-thanks {
    width: 100%;
    margin: 0;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-weight: 200;
    line-height: 1.1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--text);
}

.contact-thanks[hidden] {
    display: none;
}

/* Fields: focus keeps the ink line (no colour from the old palette), the cursor in wine red, and the browser's autofill
   tint stays out of it */
#contact .form-group input:focus,
#contact .form-group textarea:focus {
    outline: none;
    border-color: transparent;
    border-bottom-color: var(--text);
    box-shadow: inset 0 -1px 0 var(--text);   /* (the line a little bolder while you type in it, so the field in use shows) */
}

#contact .form-group input,
#contact .form-group textarea {
    caret-color: var(--wine, #6b0d1f);
}

#contact .form-group input:-webkit-autofill,
#contact .form-group input:-webkit-autofill:hover,
#contact .form-group input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--text);
    -webkit-box-shadow: 0 0 0 1000px var(--bg) inset;
    caret-color: var(--wine, #6b0d1f);
}

/* the send button keyboard-focused: the arrow goes as on hover (the lines frame it too), no browser ring */
.form-spill:focus-visible {
    outline: none;
}

.form-spill:focus-visible .form-spill-arrow {
    display: none;
}

/* the label's caption wraps in narrower columns rather than running past its photo */
.label-section .closing-caption {
    white-space: normal;
}

/* Header links: the underline draws in smoothly on hover (thin, in ink) instead of popping */
nav a.nav-link::after,
nav ul a::after {
    height: 1px;
    transition: width 0.3s ease !important;
}

/* Once sent: the heading gives way to "SPILLED", read from bottom to top, in the same column (sized by the script),
   and the thanks sits at the top of its frame */
#contact.sent h2 {
    display: none;
}

#contact .contact-spilled {
    flex: none;
    position: relative;
    width: calc(var(--work-img-h) * 2 / 3);
    margin: 0 0 0 auto;
    font-family: var(--font-mono);
    letter-spacing: 0;
    font-weight: 200;
}

#contact .contact-spilled[hidden] {
    display: none;
}

#contact.sent .contact-content {
    align-items: flex-start;
}

.spilled-word {
    position: absolute;
    display: block;
    overflow: visible;
    transform-origin: 50% 50%;
}

.spilled-word text {
    fill: var(--text);
    font-family: var(--font-mono);
    font-weight: 200;
}

@media (max-width: 768px) {
    #contact .contact-spilled {
        width: auto;
        margin: 0 var(--contact-gap, var(--side)) 0 0;
    }
}

/* The label's photo: same height (top and bottom stay), widened to run from where Spazivo starts to where Mora ends
   (two columns and the gap between them); the photo fills it, cropped as needed */
.label-section .closing-panel {
    width: calc(var(--work-img-h) * 4 / 3 + 2rem);
}

.label-section .closing-image {
    height: var(--work-img-h);
    aspect-ratio: auto;
    object-fit: cover;
}

/* "Behind the Label →" in bold with a bigger arrow; the arrow after "Spill anyway" bigger too */
.label-section .cap-behind {
    font-weight: 500;
}

.cap-arrow,
.form-spill-arrow {
    font-size: 1.6em;
    line-height: 0;
    vertical-align: -0.08em;
}

/* Philosophy in capitals */
#statement .statement-frame p {
    text-transform: uppercase;
}

/* =====================================================================================================================
   Phones (and narrow tablets): one column, easier reading. Narrower side margins (--side), the projects and services
   stacked at full width, a slightly heavier weight where the type is thin, and the header on one line with its swirl.
   ===================================================================================================================== */
@media (max-width: 768px) {
    :root {
        --side: 1.75rem;
    }

    /* header: wordmark, swirl in the middle, links, all on one line */
    nav .container {
        padding: 0.85rem var(--side);
    }

    nav .logo {
        display: block;
    }

    nav .logo svg {
        height: 24px;
    }

    nav .wordmark {
        white-space: nowrap;
        font-size: 0.68rem;
    }

    nav ul {
        gap: 0.65rem;
        margin-right: 0;
    }

    nav ul a {
        font-size: 0.68rem;
        letter-spacing: 0.04em;
    }

    /* philosophy: full width between the margins, a little heavier and larger to read */
    #statement {
        padding-left: var(--side);
        padding-right: var(--side);
    }

    #statement .container {
        padding: 0;
    }

    #statement p,
    #statement .statement-frame {
        font-size: 1.3rem;
        font-weight: 300;
    }

    .sf-top,
    .sf-bottom {
        left: calc(-1 * var(--side));
        right: calc(-1 * var(--side));
    }

    .sf-left {
        left: calc(var(--side) - var(--sf-gap));
    }

    .sf-right {
        right: calc(var(--side) - var(--sf-gap));
    }

    /* work: the three projects one under another, full width */
    section.ice {
        padding: 3rem 0 3rem var(--side);
    }

    .ice-panel {
        height: auto;
        container-type: normal;
        flex-direction: column;
        align-items: stretch;
        gap: 3rem;
        padding: 0 var(--contact-gap, var(--side)) 0 0;
    }

    .ice-item {
        width: auto;
        translate: 0 0;
    }

    /* studio */
    section.closing {
        padding-left: var(--side);
        padding-right: var(--side);
    }

    section.closing .container {
        padding: 0;
    }

    .closing-text {
        margin-top: 0;
    }

    .statement p.statement-narrow {
        font-weight: 300;
    }

    /* services: "Here's how", then each service under the other, full width */
    section.svc {
        padding-left: var(--side);
    }

    .svc-heading {
        margin-left: 0;
    }

    section.svc .svc-panel,
    section.svc:not(.svc-plain) .svc-panel {
        height: auto;
        container-type: normal;
        flex-direction: column;
        align-items: stretch;
        gap: 3rem;
        padding: var(--ice-pad-y) var(--contact-gap, var(--side)) var(--ice-pad-y) 0;
    }

    section.svc .svc-item,
    section.svc .svc-item.svc-wide {
        width: auto;
        height: auto;
    }

    .svc-plain .svc-wide p {
        max-width: none;
    }

    .svc-plain .svc-item[aria-hidden="true"] {
        display: none;
    }

    section.svc .svc-item .svc-list,
    section.svc:not(.svc-plain) .svc-item .svc-list {
        margin-top: 1.6rem;
    }

    /* the label: full width */
    .label-section {
        padding-left: var(--side);
    }

    .label-section .closing-panel {
        width: auto;
        margin: 0 var(--contact-gap, var(--side)) 0 0;
    }

    .label-section .closing-image {
        height: auto;
        aspect-ratio: 2 / 3;
    }

    /* contact: heading above the form */
    #contact {
        padding-left: var(--side);
    }

    #contact h2 {
        font-weight: 300;
    }

    .form-hint {
        font-size: 0.95rem;
    }

    footer {
        padding: 0 var(--side);
    }
}

@media (max-width: 768px) {
    /* contact heading on phones: left, with room before the form */
    #contact h2 {
        text-align: left;
        margin: 0 var(--contact-gap, var(--side)) 2.5rem 0;
    }

    /* less empty space between the studio line and the services on a small screen */
    section.svc:not(.svc-plain) {
        margin-top: 4vh;
    }
}

@media (max-width: 768px) {
    /* projects on phones: smaller (80.5% of the width), same 2:3 shape, against the right margin, captions under them */
    .ice-panel {
        align-items: flex-end;
    }

    .ice-item {
        width: 80.5%;   /* 70%, then 15% bigger */
    }
}

@media (max-width: 768px) {
    /* the label's photo on phones in the same shape as on a large screen (two columns and their gap, by one image
       height: about 1.39 : 1) */
    .label-section .closing-image {
        aspect-ratio: 1.39 / 1;
    }
}

@media (max-width: 768px) {
    /* header text on phones a tad bigger */
    nav .wordmark,
    nav ul a {
        font-size: 0.74rem;
    }
}

@media (max-width: 768px) {
    /* on phones "Have something in mind?" stays left and only "Spill" is set right */
    #contact h2 .contact-spill {
        text-align: right;
    }
}

@media (max-width: 768px) {
    /* once sent, on phones: "SPILLED" flat across the width, the thanks under it, wrapping, at a readable size; both
       held to the screen's width */
    #contact .container > * {
        align-self: stretch;
        min-width: 0;
    }

    #contact.sent .contact-content {
        min-height: 0 !important;
        margin-top: 1.5rem;
    }

    .contact-thanks {
        white-space: normal;
        font-size: 1.6rem;
        font-weight: 300;
        line-height: 1.15;
    }
}

@media (max-width: 768px) {
    /* once sent on phones, no empty space is held where the form was */
    #contact.sent .container {
        min-height: 0 !important;
    }
}

/* Bobbie's cover is a video: shown like the other covers (2:3, filling the box, the middle of the recording) */
.ice-item video {
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
    object-fit: cover;
    background: var(--bg);
}

/* Bobbie's recording: its grey (about #b0b0b0) lifted to the page's off-white; black stays black (Spazivo's photos
   keep their own colours) */
.ice-item video.cover-bob {
    filter: brightness(1.36);
}

/* Bobbie's video sits in a box of the cover's size and shape; inside it the video is a touch larger (0.8%, anchored
   at the bottom), so the thin black line along the recording's top edge falls outside the box */
.cover-crop {
    display: block;
    overflow: hidden;
}

.cover-crop video.cover-bob {
    transform: scale(1.008);
    transform-origin: 50% 100%;
}

/* Work covers: the still on top of its video in the cover's box (2:3); the still vanishes slowly (1s) when pointed at
   and comes back quickly (0.25s). (The class outranks the sitewide "no transitions" rule.) */
.cover-stack {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 2 / 3;
}

/* what's seen of the cover: normally exactly the box; pointed at, it opens up to the left (moved by the script, with
   the lines and the caption), same height, and back again after */
.cover-frame {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: block;
    overflow: hidden;
    background: var(--bg);
}

/* a still with a video under it keeps the old box's size, at its right (the box opens to the left), and only fades */
.cover-stack .cover-layer.cover-still-fixed {
    left: auto;
    width: var(--box-w, 100%);
}

/* a wide video (Bobbie's book, Spazivo's icons): smaller than the box, so the whole of it fits once the box is open
   (width and proportions set by the script), centred, its top and bottom edges fading into the background */
.cover-stack .cover-layer.cover-wide {
    inset: auto;
    top: 50%;
    left: 50%;
    width: var(--wide-w, 100%);
    height: auto;
    aspect-ratio: var(--wide-ratio, 16 / 9);
    translate: -50% -50%;
    object-fit: cover;
}

/* one sized to fit all its content (Bobbie's book): its top and bottom edges fade into the background around it; one
   that fills the box's height (Spazivo's icons) needs no fade */
.cover-stack .cover-layer.cover-wide-fit {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 9%, #000 91%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 9%, #000 91%, transparent 100%);
}

/* Bobbie: a long white strip with a fragment of a story, which the figure strolls past (vendor/bobbie-walk.js): the strip, twice in a row, the box's
   height; the figure in the middle, 80% of the box's height */
.cover-stack[data-project="bobbie"] .cover-frame {
    background: #fff;
}

.cover-stack .walk-strip {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    display: flex;
    width: max-content;
    will-change: transform;
}

.cover-stack .walk-strip img {
    display: block;
    flex: none;
    height: 100%;
    width: auto;
    max-width: none;
    aspect-ratio: 6275 / 1200;
    object-fit: fill;
}

.cover-stack .cover-walk {
    position: absolute;
    left: 50%;
    bottom: 10%;
    height: 80%;
    width: auto;
    aspect-ratio: 409 / 1400;
    translate: -50.98% 0;   /* (his body's centre line on the box's) */
    overflow: visible;
    pointer-events: none;
}

.cover-stack .cover-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.25s ease !important;
}

.cover-stack .cover-layer.on {
    opacity: 1;
}

.cover-stack .cover-still {
    transition: opacity 1s ease !important;
}

.cover-stack .cover-still.on {
    transition: opacity 0.25s ease !important;
}

/* Bobbie's screen recording: grey lifted to the page's off-white, black stays black; a touch larger (anchored at the
   bottom) so the fine line along its top edge falls outside the box */
.cover-stack .cover-layer.cover-bob {
    filter: brightness(1.36);
    transform: scale(1.008);
    transform-origin: 50% 100%;
}

/* The darker dots where lines meet: a short dotted cross centred on each crossing, in the lines' own rhythm, solid
   black and twice as thick as the lines (only where frame lines cross, not on the header's or footer's line) */
.frame-marks {
    position: absolute;
    inset: 0 0 auto 0;
    height: 0;
    z-index: 2;
    pointer-events: none;
    visibility: hidden;
    --mark: #000;
}

.frame-marks.on {
    visibility: visible;
}

.fmark {
    position: absolute;
    top: 0;
    left: 0;
    width: 55px;
    height: 55px;
}

.fmark i {
    position: absolute;
    display: block;
}

.fmark .fm-h {
    left: 0;
    top: 26.5px;
    width: 55px;
    height: 2px;
    background: linear-gradient(to right, var(--mark) 2px, transparent 2px) 0 0 / 7px 2px repeat-x;
}

.fmark .fm-v {
    left: 26.5px;
    top: 0;
    width: 2px;
    height: 55px;
    background: linear-gradient(to bottom, var(--mark) 2px, transparent 2px) 0 0 / 2px 7px repeat-y;
}

/* the dark dots fade out along the line, strongest at the crossing, melting into the line's own dots */
.fmark .fm-h {
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 42%, #000 58%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0%, #000 42%, #000 58%, transparent 100%);
}

.fmark .fm-v {
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 42%, #000 58%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, #000 42%, #000 58%, transparent 100%);
}

/* The cursor (cursor.js): an empty dot, filled over anything clickable; the system cursor is hidden only once the
   script has taken over, and only with a mouse or trackpad */
html.has-dot-cursor,
html.has-dot-cursor * {
    cursor: none !important;
}

.cursor-dot {
    position: fixed;
    top: 0;
    left: 0;
    width: 15px;
    height: 15px;
    margin: -7.5px 0 0 -7.5px;
    border: 1px solid var(--text);
    border-radius: 50%;
    background: transparent;
    pointer-events: none;
    z-index: 2147483647;
    opacity: 0;
    transition: background-color 0.15s ease, opacity 0.15s ease, width 0.2s ease, height 0.2s ease,
        margin 0.2s ease !important;
}

/* shaking the mouse to find it: big for as long as the shaking lasts (cursor.js), same thin line */
.cursor-dot.is-big {
    width: 60px;
    height: 60px;
    margin: -30px 0 0 -30px;
}

.cursor-dot.is-shown {
    opacity: 1;
}

.cursor-dot.is-full {
    background: var(--text);
}

/* No underlines anywhere, on hover or otherwise: the cursor filling in is the only sign something is clickable */
a,
a:hover,
a:focus-visible {
    text-decoration: none !important;
}

nav a::after,
nav a:hover::after {
    content: none !important;
}


/* the crossing marks stop at the screen's edges (a mark on a line near the edge mustn't let the page scroll sideways) */
.frame-marks {
    overflow-x: clip;
}

/* a live animation as a project's moving piece (Spazivo's icons, work/spazivo_hover.svg): its 2:3 composition sized so
   the person fits the box, placed so the dot (at 38.3% of its height) is in the box's middle; its pieces travel to the
   open box's edges (clipped there) */
.cover-stack .cover-live {
    position: absolute;
    top: 18.92%;
    left: 50%;
    width: auto;
    height: 81.1%;
    aspect-ratio: 2 / 3;
    translate: -50% 0;
    overflow: visible;
}

.cover-live .sp-icon:not(.sp-roof) {
    visibility: hidden;
}

/* a still on its own (no moving piece; Lucky Duck's photo) fills the box, and the opened box too (a little less of its
   top and bottom showing then) */
.cover-stack .cover-layer.cover-still:not(.cover-still-fixed) {
    object-fit: cover;
}

@media (max-width: 768px) {
    /* header on phones: the links' list takes the links' own size and line height (it had the page's 16px, which sat
       the small link text lower than SPILLED SODA), so wordmark and links share one line; and iPhones don't enlarge
       the text on their own */
    html {
        -webkit-text-size-adjust: 100%;
        text-size-adjust: 100%;
    }

    nav ul,
    nav ul li {
        font-size: 0.74rem;
        line-height: 1.6;
    }

    nav .wordmark {
        line-height: 1.6;
    }

    /* (the bar keeps its height: what the taller list used to add now sits in the padding) */
    nav .container {
        padding-top: calc(0.85rem + 3.5px);
        padding-bottom: calc(0.85rem + 3.5px);
    }
}

/* Phones held sideways (wide enough for the side-by-side layout, but short, and touch): the services and "And after
   launch?" use the whole width between the side margins (from SPILLED SODA to CONTACT) instead of staying under the
   project columns on the right */
@media (min-width: 769px) and (max-height: 500px) and (hover: none) {
    .svc-heading {
        margin-left: 0;
    }

    section.svc .svc-panel {
        justify-content: flex-start;
        padding-left: 0;
    }

    section.svc .svc-item {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
    }

    .svc-plain .svc-item.svc-wide {
        flex: 1 1 100%;
        width: auto;
    }

    .svc-plain .svc-wide p {
        max-width: none;
    }

    .svc-plain .svc-item[aria-hidden="true"] {
        display: none;
    }
}

/* Phones held sideways, once sent: as on an upright phone, "SPILLED" reads normally (flat, not turned), across the
   width between the side margins, with the thanks underneath, wrapping at a readable size */
@media (min-width: 769px) and (max-height: 500px) and (hover: none) {
    #contact.sent .container {
        flex-direction: column;
        align-items: stretch;
        min-height: 0 !important;
    }

    #contact.sent .contact-spilled {
        width: auto;
        margin: 0 var(--contact-gap, 4rem) 0 0;
    }

    #contact.sent .contact-content {
        width: auto;
        min-height: 0 !important;
        margin: 1.5rem var(--contact-gap, 4rem) 0 0;
    }

    #contact.sent .contact-thanks {
        white-space: normal;
        font-size: 1.6rem;
        font-weight: 300;
        line-height: 1.15;
    }
}

/* Touch screens: each header link gets an invisible touch area of about 46px around its text (the links themselves
   don't move or change); neighbouring areas meet but don't overlap */
@media (max-width: 768px), (hover: none) {
    nav ul a::before,
    nav .wordmark::before {
        content: '';
        position: absolute;
        inset: -16px -5px;
    }

    nav .logo::before {
        content: '';
        position: absolute;
        inset: -11px -8px;
    }
}

/* Read by screen readers and search engines, not shown (and taking no space) */
.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0 0 0 0) !important;
    clip-path: inset(50%) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Contact: if a message doesn't go through, a note under the button (like the field notes, in the swirl's wine red);
   and under the form, the address to write to directly (set like the labels); once sent, only the thanks remains */
.form-error {
    margin-top: 1.25rem;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-weight: 300;
    letter-spacing: 0.04em;
    color: var(--wine, #6b0d1f);
}

.form-error[hidden] {
    display: none;
}

.form-error {
    line-height: 1.6;
}

.form-error-title {
    font-weight: 500;
}

.form-error a {
    color: inherit;
}

.contact-email {
    margin-top: 1.75rem;
    text-align: right;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-weight: 300;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.contact-email a {
    color: inherit;
}

#contact.sent .contact-email {
    display: none;
}

/* the footer's address: in the footer's own type; on phones on a line of its own */
footer a {
    color: inherit;
}

@media (max-width: 768px) {
    footer {
        height: auto;
        min-height: var(--header-h, 57.6px);
        padding-top: 0.9rem;
        padding-bottom: 0.9rem;
    }

    footer p {
        line-height: 1.8;
    }

    .footer-email {
        display: block;
    }

    .footer-dot {
        display: none;
    }
}

/* Privacy policy and legal notice: plain reading text in the site's type, a comfortable line length */
.legal-page section {
    max-width: 44rem;
    margin: 2.5rem 0 0;
    padding: 0;
    opacity: 1;
    min-height: 0;
    text-align: left;
}

.legal-page h2 {
    text-align: left;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 0.9rem;
}

.legal-page section p,
.legal-page .legal-date {
    font-family: var(--font-mono);
    font-size: 0.9rem;
    font-weight: 300;
    line-height: 1.75;
    max-width: 44rem;
}

.legal-page section p + p {
    margin-top: 0.9rem;
}

.legal-page a {
    color: inherit;
}

/* still to be filled in before launch (shown highlighted so nothing is missed) */
.legal-page .todo {
    background: #fff3a8;
}

/* the footer's links to the privacy policy and the legal notice: on phones on a line of their own */
@media (max-width: 768px) {
    .footer-legal {
        display: block;
    }
}

/* a slideshow cover (Lucky Duck): square images filling the box (the middle of each in the tall closed box), each fading
   in over the last */
.cover-stack .cover-layer.cover-slide {
    object-fit: cover;
    transition: opacity 0.4s ease !important;
}

/* Lucky Duck's story: a square stage (backgrounds and objects as layers), as tall as the box and centred in it, so the
   closed box shows its middle and the opened, about square box all of it; before it's pointed at only background 1 and
   the two booklets show */
.story-stage {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--story-s, 100%);
    height: var(--story-s, 100%);
    translate: -50% -50%;
    overflow: hidden;
}

.story-stage img {
    position: absolute;
    display: block;
    max-width: none;
    aspect-ratio: auto;
    object-fit: fill;          /* (each object exactly as drawn, in its box; not the project images' 2:3 crop) */
}

.story-stage .story-bg {
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
}

.story-stage .story-bg.story-first {
    opacity: 1;
}

.story-stage .story-obj {
    visibility: hidden;
}

.story-stage .story-obj.story-cover {
    visibility: visible;
}

/* for keyboards: the first thing to tab to, out of sight until then */
.skip-link {
    position: fixed;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 1000;
    padding: 0.5rem 0.75rem;
    background: var(--text);
    color: var(--bg);
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transform: translateY(-300%);
}

.skip-link:focus {
    transform: none;
}


/* the homepage's main content as one landmark for screen readers; it adds no box of its own, so the layout is as before */
.home-main {
    display: contents;
}

/* reached with the keyboard before the header has come in (during the opening): the header's links show at once, in
   their place, over whatever the opening is doing, so a focused link is never invisible */
nav:focus-within ul,
nav:focus-within .logo,
nav:focus-within .wordmark {
    opacity: 1 !important;
    transform: none !important;
}

/* 404: the page fills the screen so the footer stays at the bottom */
.not-found {
    min-height: calc(100vh - 4rem);
    min-height: calc(100svh - 4rem);
}

.not-found .not-found-text {
    font-family: var(--font-mono);
    font-size: 0.9rem;
    font-weight: 300;
    line-height: 1.75;
    max-width: 44rem;
    margin-bottom: 3rem;
}

.not-found .not-found-link a {
    color: inherit;
}

/* =====================================================================================================================
   Tablets held upright (iPad portrait: wider than a phone, taller than wide, touch). Only here, nowhere else.
   ===================================================================================================================== */
@media (min-width: 769px) and (orientation: portrait) and (hover: none) {
    /* philosophy: its right border halfway between SERVICES and CONTACT in the header, the type a
       little larger (a size the site already uses) with more space between the lines and paragraphs, so the frame is
       wider and taller */
    .sf-right {
        left: var(--svc-contact-mid, calc(100vw - 9rem));
    }

    #statement .statement-frame {
        max-width: calc(var(--svc-contact-mid, calc(100vw - 9rem)) - var(--sf-gap) - 4rem);
        font-size: 1.52rem;
    }

    #statement p {
        font-size: 1.52rem;
        line-height: 1.5;
    }

    #statement .statement-frame > p + p {
        margin-top: 1.1em;
    }
    /* the frames (projects, services, closing) as tall as their content plus some air, not a whole screen tall, so
       the chapters sit closer together: the image height the width allows, its caption, and 4rem above and below */
    /* the project images a little larger (the grid's columns, here and on the case pages, are as wide as one), so
       the margin column on the left is narrower */
    :root {
        --work-img-h: min(100vh - var(--nav-h, 59px) - 1rem - 26px - 3rem - 5.3rem, 0.45 * (100vw - 14rem));
        --frame-h: calc(var(--work-img-h) + 4.5rem + 3rem + 8rem);
    }

    .ice-panel {
        height: var(--frame-h);
    }

    .closing-row {
        --panel-h: var(--frame-h);
    }

    .svc-panel {
        height: calc(var(--frame-h) * 0.48);
    }

    section.svc + section.svc {
        padding-top: calc(var(--frame-h) * 0.04);
    }
}
