/* =========================================================================
   Theme: Chroma Lab
   A loud, very colourful neo-brutalist theme for graphic designers.

   Rules it keeps: flat colour only, 3px ink rules, hard offset shadows, no
   gradients and no blur. Every colour comes from the shared palette tokens in
   templates/shared/base.css, so the studio's palette panel still repaints the
   whole theme one token at a time.

   No JavaScript. Everything that moves is CSS, and every bit of it sits inside
   `prefers-reduced-motion: no-preference` so a visitor who asked for less
   movement gets a completely still page rather than a fast one.
   ========================================================================= */

.theme-chroma-lab {
    --rule: 3px solid var(--ink);
    --rule-fat: 5px solid var(--ink);
    --pop: 6px 6px 0 var(--ink);
    --pop-lg: 12px 12px 0 var(--ink);
    --shell: 78rem;

    background: var(--paper);

    /* A faint grid, drawn rather than loaded — the whole site makes no
       external requests and a theme should not be the one that starts. */
    background-image:
        linear-gradient(to right, rgba(20, 18, 16, 0.055) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(20, 18, 16, 0.055) 1px, transparent 1px);
    background-size: 26px 26px;
}

.cl-shell {
    width: 100%;
    max-width: var(--shell);
    margin: 0 auto;
    padding-inline: 1.15rem;
}

/* Palette chips, reused everywhere a colour needs naming. */
.cl-chip--yellow { background: var(--yellow); }
.cl-chip--cyan   { background: var(--cyan); }
.cl-chip--pink   { background: var(--pink); }
.cl-chip--lime   { background: var(--lime); }
.cl-chip--orange { background: var(--orange); }
.cl-chip--purple { background: var(--purple); }

/* Per-card accent, set from the project's own accent value. */
.cl-accent--cyan   { --card: var(--cyan); }
.cl-accent--orange { --card: var(--orange); }
.cl-accent--lime   { --card: var(--lime); }
.cl-accent--purple { --card: var(--purple); }
.cl-accent--pink   { --card: var(--pink); }
.cl-accent--yellow { --card: var(--yellow); }

/* -------------------------------------------------------------------------
   Top bar
   ------------------------------------------------------------------------- */
.cl-bar {
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--paper);
    border-bottom: var(--rule-fat);
}

.cl-bar__rail { display: flex; height: 8px; }
.cl-bar__rail > span { flex: 1; }

.cl-bar__inner {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding-block: 0.7rem;
}

.cl-bar__name {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    /* A flex item will not shrink below its content by default, and a long
       display name plus four nav links adds up to more than a narrow phone
       has. These let the name give way instead of widening the page. */
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-family: var(--font-display);
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: -0.01em;
}
.cl-bar__mark {
    display: grid;
    place-items: center;
    flex: none;
    width: 2rem;
    height: 2rem;
    background: var(--yellow);
    border: var(--rule);
    box-shadow: var(--sh-sm);
    font-size: 0.78rem;
}

.cl-bar__nav {
    display: flex;
    gap: 1.1rem;
    margin-left: auto;
    font-weight: 800;
    font-size: 0.86rem;
    text-transform: uppercase;
}
.cl-bar__nav a { padding-block: 0.2rem; border-bottom: 3px solid transparent; }
.cl-bar__nav a:hover { border-bottom-color: var(--ink); }

.cl-bar__status {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    background: var(--lime);
    border: var(--rule);
    box-shadow: var(--sh-sm);
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
}

.cl-bar__dot {
    width: 0.55rem;
    height: 0.55rem;
    background: var(--ink);
    border-radius: 50%;
}

/* -------------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------------- */
.cl-hero {
    position: relative;
    overflow: hidden;
    border-bottom: var(--rule-fat);
}

.cl-hero__deco { position: absolute; inset: 0; pointer-events: none; }

/* The marks live in the gutter between the type and the photograph, running
   down it as a loose diagonal. Keeping them out from behind the portrait is
   deliberate: half a circle poking out from under a framed photo reads as a
   mistake rather than as a decision. */
.cl-blob { position: absolute; border: var(--rule); }
.cl-blob--1 {
    top: 26%; right: 29%;
    width: 6.5rem; height: 6.5rem;
    background: var(--purple);
    border-radius: 50%;
}
.cl-blob--2 {
    bottom: 8%; right: 23%;
    width: 4.6rem; height: 4.6rem;
    background: var(--pink);
    transform: rotate(14deg);
}
.cl-blob--3 {
    bottom: 30%; right: 41%;
    width: 3.2rem; height: 3.2rem;
    background: var(--cyan);
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
    border: none;
}

/* A registration mark, the way a print job is lined up. */
.cl-reg {
    position: absolute;
    top: 11%; right: 36%;
    width: 4.5rem; height: 4.5rem;
    border: var(--rule);
    border-radius: 50%;
    background:
        linear-gradient(to right, var(--ink) 0 100%) center / 100% 3px no-repeat,
        linear-gradient(to bottom, var(--ink) 0 100%) center / 3px 100% no-repeat;
    opacity: 0.5;
}

.cl-hero__inner {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 2.5rem;
    align-items: center;
    padding-block: clamp(2.5rem, 6vw, 4.5rem);
}

.cl-kicker {
    display: inline-flex;
    align-items: stretch;
    margin-bottom: 1.1rem;
    border: var(--rule);
    box-shadow: var(--sh-sm);
    font-size: 0.72rem;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.1em;
}
.cl-kicker__box  { padding: 0.35rem 0.7rem; background: var(--yellow); }
.cl-kicker__year { padding: 0.35rem 0.7rem; background: var(--ink); color: var(--paper); }

.cl-hero__name {
    display: grid;
    font-family: var(--font-display);
    /* Sized from the longest word so a long surname cannot spill the column.
       template.php counts the characters and passes --name-len.

       The divisor is set against a measured ~0.72em per uppercase character in
       Arial Black, minus the portrait column, the gutter, the shell padding
       and a scrollbar. Guessing narrower than the face really is was what made
       a ten-letter surname 57px wider than the column it sits in. */
    font-size: clamp(2.3rem, calc(72vw / var(--name-len, 8)), 6.2rem);
    line-height: 0.86;
    letter-spacing: -0.035em;
    text-transform: uppercase;
}

.cl-hero__line { display: block; }
/* Every other line is knocked out to an outline — a type-specimen trick, and
   the reason the name reads as a designer's mark rather than a heading. */
.cl-hero__line:nth-child(even) {
    color: transparent;
    -webkit-text-stroke: 2px var(--ink);
}

.cl-hero__role {
    margin-top: 1rem;
    font-family: var(--font-mono);
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.cl-hero__tagline {
    max-width: 34rem;
    margin-top: 0.9rem;
    padding-left: 0.9rem;
    border-left: 6px solid var(--cyan);
    font-size: clamp(1rem, 2vw, 1.15rem);
}

.cl-hero__cta { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 1.6rem; }

.cl-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.8rem 1.3rem;
    background: var(--paper);
    border: var(--rule);
    box-shadow: var(--pop);
    font-family: var(--font-display);
    font-size: 0.82rem;
    text-transform: uppercase;
    transition: transform 0.14s var(--ease-pop), box-shadow 0.14s var(--ease-pop);
}
.cl-btn--solid { background: var(--yellow); }
.cl-btn:hover { transform: translate(-3px, -3px); box-shadow: 10px 10px 0 var(--ink); }
.cl-btn:active { transform: translate(3px, 3px); box-shadow: none; }
.cl-btn__arrow { transition: transform 0.14s var(--ease-pop); }
.cl-btn:hover .cl-btn__arrow { transform: translateX(4px); }

.cl-hero__where {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 1.3rem;
    font-size: 0.85rem;
    font-weight: 700;
}

/* Portrait ---------------------------------------------------------------- */
/* Capped rather than left to fill its column. The photograph is a strong
   element and the name has to stay the loudest thing on the page. */
.cl-hero__side {
    display: grid;
    gap: 1.4rem;
    width: 100%;
    max-width: 20rem;
    justify-self: end;
}

.cl-portrait {
    position: relative;
    background: var(--cyan);
    border: var(--rule-fat);
    box-shadow: var(--pop-lg);
}

/* Two offset colour plates behind the frame, like a mis-registered print. */
.cl-portrait::before,
.cl-portrait::after {
    content: "";
    position: absolute;
    inset: 0;
    border: var(--rule);
    z-index: -1;
}
.cl-portrait::before { background: var(--pink);   transform: translate(14px, 14px) rotate(2.5deg); }
.cl-portrait::after  { background: var(--yellow); transform: translate(-12px, 10px) rotate(-3deg); }

.cl-portrait__img {
    width: 100%;
    /* `height: auto` is doing real work. The markup carries width="1000"
       height="1000" so the browser can reserve the space before the file
       arrives, and those attributes become a presentational `height: 1000px`.
       While height is not auto, `aspect-ratio` is ignored — leaving a 320px
       wide photograph a thousand pixels tall. */
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    /* This used to be greyscale until hovered. On a touchscreen there is no
       hover, so for most visitors the owner's photograph was simply black and
       white with no way to see it otherwise — an effect nobody asked for,
       applied to the one thing on the page that is a picture of a person. */
    transition: filter 0.3s ease;
}

.cl-portrait__monogram {
    display: grid;
    place-items: center;
    aspect-ratio: 1 / 1;
    background: var(--yellow);
    font-family: var(--font-display);
    font-size: clamp(3rem, 12vw, 6rem);
    text-transform: uppercase;
}

.cl-portrait__tag {
    position: absolute;
    left: -0.6rem;
    bottom: -1rem;
    padding: 0.4rem 0.75rem;
    background: var(--ink);
    color: var(--paper);
    border: var(--rule);
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
}

.cl-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(5.5rem, 100%), 1fr));
    gap: 0.6rem;
    margin-top: 0.8rem;
}
.cl-stats__item {
    padding: 0.65rem 0.7rem;
    background: var(--paper);
    border: var(--rule);
    box-shadow: var(--sh-sm);
}
.cl-stats__item:nth-child(3n + 1) { background: var(--lime); }
.cl-stats__item:nth-child(3n + 2) { background: var(--orange); }
.cl-stats__item:nth-child(3n + 3) { background: var(--purple); }
.cl-stats dt {
    font-family: var(--font-display);
    font-size: 1.6rem;
    line-height: 1;
}
.cl-stats dd {
    margin: 0.15rem 0 0;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
}

/* -------------------------------------------------------------------------
   Skills ticker
   ------------------------------------------------------------------------- */
.cl-ticker {
    overflow: hidden;
    background: var(--ink);
    color: var(--paper);
    border-bottom: var(--rule-fat);
}
.cl-ticker__track {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    width: max-content;
    padding-block: 0.7rem;
}
.cl-ticker__item {
    font-family: var(--font-display);
    font-size: 1rem;
    text-transform: uppercase;
    white-space: nowrap;
}
.cl-ticker__star { color: var(--yellow); }

/* -------------------------------------------------------------------------
   Sections and headings
   ------------------------------------------------------------------------- */
.cl-section { padding-block: clamp(2.8rem, 7vw, 5rem); border-bottom: var(--rule-fat); }
.cl-section--work { background: var(--paper-2); }
.cl-section--about { background: var(--ink); color: var(--paper); }
.cl-section--craft { background: var(--paper); }
.cl-section--track { background: var(--paper-2); }

.cl-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 2rem;
    padding-bottom: 0.9rem;
    border-bottom: var(--rule);
}

.cl-head__title {
    font-family: var(--font-display);
    font-size: clamp(1.9rem, 6vw, 3.4rem);
    line-height: 0.95;
    letter-spacing: -0.03em;
    text-transform: uppercase;
}
.cl-head__title--light { border: 0; }

.cl-head__hl {
    display: inline-block;
    padding: 0 0.35rem;
    background: var(--yellow);
    border: var(--rule);
    box-shadow: var(--sh-sm);
    transform: rotate(-1.5deg);
}
.cl-head__hl--pink { background: var(--pink); }
.cl-head__hl--lime { background: var(--lime); }

.cl-head__meta {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
}

.cl-sub {
    margin-bottom: 1.1rem;
    font-family: var(--font-display);
    font-size: 1.05rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* -------------------------------------------------------------------------
   Work
   ------------------------------------------------------------------------- */
.cl-work {
    display: grid;
    /* `min(19rem, 100%)` rather than a bare 19rem: a plain minmax() floor
       cannot shrink, so on a 320px phone the track stays 304px wide, adds the
       shell padding, and slides the whole page sideways. */
    grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr));
    gap: 1.6rem;
}

.cl-card {
    display: flex;
    flex-direction: column;
    background: var(--paper);
    border: var(--rule-fat);
    box-shadow: var(--pop);
    transition: transform 0.18s var(--ease-pop), box-shadow 0.18s var(--ease-pop);
}
.cl-card:hover {
    transform: translate(-4px, -6px) rotate(-0.7deg);
    box-shadow: var(--pop-lg);
}

/* The picture ------------------------------------------------------------- */
.cl-poster {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--card, var(--cyan));
    border-bottom: var(--rule-fat);
}

/* The shared flat artwork sits underneath as the colour bed. */
.cl-poster .art {
    position: absolute;
    inset: 0;
    aspect-ratio: auto;
    background: var(--card, var(--cyan));
}

/* A photograph fills the same frame. The colour bed would only show as a hairline
   behind a `cover` image, so it goes flat white instead of the accent, and the
   picture gets the slow zoom the motif has on the drawn variant. */
.cl-poster--shot { background: var(--paper); }
.cl-poster--shot .art { background: var(--paper); }
.cl-poster--shot .art__photo { transition: transform 0.4s var(--ease-pop); }
.cl-card:hover .cl-poster--shot .art__photo { transform: scale(1.05); }

/* …and the shipped line motif is printed over it, on its own paper panel.
   Which motif appears is decided by the artwork variant the owner already
   picked, so the picture follows their choice instead of being random.

   The panel is not decoration. The artwork variants underneath range from four
   pale blocks to a near-solid slab of ink, and drawing ink linework straight
   onto that makes half of them vanish. On its own sheet the motif reads the
   same on every one of the six, and the colour bed becomes a border around it. */
.cl-poster__motif {
    position: absolute;
    inset: 11%;
    background-color: var(--paper);
    background-position: center;
    background-repeat: no-repeat;
    background-size: 76%;
    border: var(--rule);
    box-shadow: var(--sh);
    transform: rotate(-1.4deg);
    transition: transform 0.35s var(--ease-pop);
}
.cl-card:hover .cl-poster__motif { transform: rotate(1deg) scale(1.03); }

.cl-poster--grid  .cl-poster__motif { background-image: url("img/motif-grid.svg"); }
.cl-poster--orbit .cl-poster__motif { background-image: url("img/motif-orbit.svg"); }
.cl-poster--wave  .cl-poster__motif { background-image: url("img/motif-wave.svg"); }
.cl-poster--stack .cl-poster__motif { background-image: url("img/motif-stack.svg"); }
.cl-poster--split .cl-poster__motif { background-image: url("img/motif-split.svg"); }
.cl-poster--type  .cl-poster__motif { background-image: url("img/motif-type.svg"); }

.cl-poster__no {
    position: absolute;
    top: 0; left: 0;
    padding: 0.3rem 0.7rem;
    background: var(--ink);
    color: var(--paper);
    border-right: var(--rule);
    border-bottom: var(--rule);
    font-family: var(--font-display);
    font-size: 0.9rem;
}

.cl-card__body { display: grid; gap: 0.5rem; padding: 1rem 1.05rem 1.2rem; }

.cl-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.cl-card__cat {
    padding: 0.15rem 0.45rem;
    background: var(--card, var(--cyan));
    border: 2px solid var(--ink);
}
.cl-card__year { font-family: var(--font-mono); }

.cl-card__title {
    font-family: var(--font-display);
    font-size: 1.45rem;
    line-height: 1.02;
    text-transform: uppercase;
}
/* Every card already lifts on hover, so a linked one only needs to say so in
   the title. */
.cl-card__link { display: inline-flex; align-items: baseline; gap: 0.3rem; }
.cl-card__link:hover { text-decoration: underline; text-underline-offset: 4px; }
.cl-card__out { font-size: 0.66em; }

.cl-card__blurb { font-size: 0.92rem; }

.cl-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.2rem; }
.cl-tags li {
    padding: 0.15rem 0.5rem;
    background: var(--paper-2);
    border: 2px solid var(--ink);
    font-size: 0.68rem;
    font-weight: 800;
    text-transform: uppercase;
}

/* -------------------------------------------------------------------------
   Studio / about — the one dark band
   ------------------------------------------------------------------------- */
.cl-about {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 2.2rem;
    align-items: start;
}
.cl-about__text .cl-head__title { margin-bottom: 1.2rem; }
.cl-about__para { margin-bottom: 0.9rem; max-width: 46rem; font-size: 1rem; }

.cl-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1.2rem; }
.cl-chips li {
    padding: 0.3rem 0.65rem;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule);
    box-shadow: 3px 3px 0 var(--cyan);
    font-size: 0.75rem;
    font-weight: 800;
    text-transform: uppercase;
    transition: transform 0.14s var(--ease-pop), box-shadow 0.14s var(--ease-pop);
}
.cl-chips li:nth-child(4n + 2) { box-shadow: 3px 3px 0 var(--pink); }
.cl-chips li:nth-child(4n + 3) { box-shadow: 3px 3px 0 var(--lime); }
.cl-chips li:nth-child(4n + 4) { box-shadow: 3px 3px 0 var(--orange); }
.cl-chips li:hover { transform: translate(-2px, -2px); }

.cl-swatches {
    padding: 1.1rem;
    background: var(--paper);
    color: var(--ink);
    border: var(--rule-fat);
    box-shadow: 10px 10px 0 var(--purple);
}
.cl-swatches__label {
    margin-bottom: 0.7rem;
    font-family: var(--font-display);
    font-size: 0.8rem;
    text-transform: uppercase;
}
.cl-swatches__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }

.cl-swatch {
    display: grid;
    align-content: end;
    aspect-ratio: 1 / 1;
    padding: 0.35rem;
    border: var(--rule);
    transition: transform 0.14s var(--ease-pop);
}
.cl-swatch:hover { transform: translateY(-4px) rotate(-2deg); }
.cl-swatch__name {
    font-size: 0.6rem;
    font-weight: 900;
    text-transform: uppercase;
}

.cl-swatches__note {
    margin-top: 0.8rem;
    font-size: 0.78rem;
    font-family: var(--font-mono);
}

/* -------------------------------------------------------------------------
   Craft / services
   ------------------------------------------------------------------------- */
.cl-services {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: 1.2rem;
}

.cl-service {
    padding: 1.2rem 1.1rem 1.4rem;
    background: var(--paper);
    border: var(--rule-fat);
    box-shadow: var(--pop);
    transition: transform 0.16s var(--ease-pop), box-shadow 0.16s var(--ease-pop);
}
.cl-service:hover { transform: translate(-3px, -3px); box-shadow: var(--pop-lg); }

.cl-service__rule { display: block; height: 0.9rem; margin-bottom: 0.9rem; border: var(--rule); }
.cl-service:nth-child(6n + 1) .cl-service__rule { background: var(--cyan); }
.cl-service:nth-child(6n + 2) .cl-service__rule { background: var(--pink); }
.cl-service:nth-child(6n + 3) .cl-service__rule { background: var(--lime); }
.cl-service:nth-child(6n + 4) .cl-service__rule { background: var(--orange); }
.cl-service:nth-child(6n + 5) .cl-service__rule { background: var(--purple); }
.cl-service:nth-child(6n + 6) .cl-service__rule { background: var(--yellow); }

.cl-service__title {
    margin-bottom: 0.45rem;
    font-family: var(--font-display);
    font-size: 1.2rem;
    text-transform: uppercase;
}
.cl-service__blurb { font-size: 0.92rem; }

/* -------------------------------------------------------------------------
   Experience and recognition
   ------------------------------------------------------------------------- */
.cl-track {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: 2.2rem;
    align-items: start;
}

.cl-exp { display: grid; gap: 0.9rem; }
.cl-exp__row {
    display: grid;
    grid-template-columns: 7.5rem minmax(0, 1fr);
    gap: 0.9rem;
    padding: 0.9rem 1rem;
    background: var(--paper);
    border: var(--rule);
    box-shadow: var(--sh-sm);
}
.cl-exp__period {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    font-weight: 700;
}
/* `min-width: 0` because a flex item will not shrink below its own content
   otherwise, and an uppercase display role next to a mark overruns a phone. */
.cl-exp__who { display: flex; align-items: flex-start; gap: 0.65rem; }
.cl-exp__who > span { min-width: 0; overflow-wrap: anywhere; }
.cl-exp__logo {
    flex: none;
    width: 2.4rem;
    height: 2.4rem;
    object-fit: cover;
    background: var(--paper);
    border: var(--rule);
}
.cl-exp__role { display: block; font-family: var(--font-display); font-size: 1rem; text-transform: uppercase; }
.cl-exp__org  { display: block; font-size: 0.82rem; font-weight: 700; }
.cl-exp__org a:hover { text-decoration: underline; text-underline-offset: 3px; }
.cl-exp__org span { font-size: 0.85em; }
.cl-exp__note { margin-top: 0.3rem; font-size: 0.88rem; }

.cl-recog { display: grid; gap: 0.6rem; }
.cl-recog__row {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: 0.7rem;
    align-items: start;
    padding: 0.7rem 0.8rem;
    background: var(--paper);
    border: var(--rule);
}
.cl-recog__row:nth-child(3n + 1) { box-shadow: 4px 4px 0 var(--pink); }
.cl-recog__row:nth-child(3n + 2) { box-shadow: 4px 4px 0 var(--cyan); }
.cl-recog__row:nth-child(3n + 3) { box-shadow: 4px 4px 0 var(--lime); }
.cl-recog__year { font-family: var(--font-display); font-size: 0.95rem; }
.cl-recog__text { font-size: 0.88rem; }

/* -------------------------------------------------------------------------
   Contact
   ------------------------------------------------------------------------- */
.cl-contact {
    position: relative;
    padding-block: clamp(3rem, 9vw, 6rem);
    background: var(--yellow);
    border-bottom: var(--rule-fat);
}

.cl-contact__title {
    max-width: 22ch;
    font-family: var(--font-display);
    font-size: clamp(2rem, 7vw, 4.2rem);
    line-height: 0.94;
    letter-spacing: -0.03em;
    text-transform: uppercase;
}
.cl-contact__hl {
    display: inline-block;
    padding: 0 0.4rem;
    background: var(--ink);
    color: var(--yellow);
    transform: rotate(-2deg);
}

.cl-contact__mail {
    display: inline-block;
    margin-top: 1.6rem;
    padding: 0.7rem 1.1rem;
    background: var(--paper);
    border: var(--rule-fat);
    box-shadow: var(--pop);
    font-family: var(--font-mono);
    font-size: clamp(0.95rem, 2.4vw, 1.4rem);
    font-weight: 700;
    /* A long address must wrap rather than widen the page. */
    overflow-wrap: anywhere;
    transition: transform 0.14s var(--ease-pop), box-shadow 0.14s var(--ease-pop);
}
.cl-contact__mail:hover { transform: translate(-3px, -3px); box-shadow: var(--pop-lg); }

.cl-links {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    gap: 0.7rem;
    margin-top: 2rem;
}
.cl-links__item > a,
.cl-links__static {
    display: grid;
    gap: 0.1rem;
    height: 100%;
    padding: 0.7rem 0.85rem;
    background: var(--paper);
    border: var(--rule);
    box-shadow: var(--sh-sm);
    transition: transform 0.14s var(--ease-pop), box-shadow 0.14s var(--ease-pop);
}
.cl-links__item > a:hover { transform: translate(-3px, -3px); box-shadow: var(--pop); }
.cl-links__label  { font-family: var(--font-display); font-size: 0.8rem; text-transform: uppercase; }
.cl-links__handle { font-size: 0.8rem; overflow-wrap: anywhere; }

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */
.cl-foot { padding-block: 1.4rem; background: var(--ink); color: var(--paper); }
.cl-foot__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    font-size: 0.82rem;
    font-weight: 700;
}
.cl-foot__marks { display: flex; gap: 0.3rem; }
.cl-foot__marks > span { width: 1.1rem; height: 1.1rem; border: 2px solid var(--paper); }

/* -------------------------------------------------------------------------
   Motion

   All of it lives behind `no-preference`. A visitor who has asked for less
   movement gets a page that never moves at all, rather than one that moves
   very fast — which is what a plain duration override would leave them with.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

    @keyframes cl-drift {
        0%, 100% { transform: translateY(0) rotate(var(--rot, 0deg)); }
        50%      { transform: translateY(-18px) rotate(calc(var(--rot, 0deg) + 6deg)); }
    }

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

    @keyframes cl-pulse {
        0%, 100% { transform: scale(1); opacity: 1; }
        50%      { transform: scale(0.55); opacity: 0.55; }
    }

    @keyframes cl-scroll-x { to { transform: translateX(-50%); } }

    @keyframes cl-rise {
        from { opacity: 0; transform: translateY(28px); }
        to   { opacity: 1; transform: translateY(0); }
    }

    @keyframes cl-pop-in {
        from { opacity: 0; transform: translateY(26px) rotate(-1.5deg); }
        to   { opacity: 1; transform: translateY(0) rotate(0deg); }
    }

    .cl-blob--1 { --rot: 0deg;   animation: cl-drift 9s ease-in-out infinite; }
    .cl-blob--2 { --rot: 14deg;  animation: cl-drift 7s ease-in-out infinite reverse; }
    .cl-blob--3 { --rot: 0deg;   animation: cl-drift 11s ease-in-out infinite 0.8s; }
    .cl-reg     { animation: cl-spin 18s linear infinite; }
    .cl-bar__dot { animation: cl-pulse 1.8s ease-in-out infinite; }

    .cl-ticker__track { animation: cl-scroll-x 34s linear infinite; }
    .cl-ticker:hover .cl-ticker__track { animation-play-state: paused; }

    /* Hero entrance, staggered. `both` fill means the end state is what sticks,
       so nothing can be left stranded at opacity 0. */
    .cl-hero__line   { animation: cl-rise 0.7s var(--ease-pop) both; }
    .cl-hero__line:nth-child(2) { animation-delay: 0.09s; }
    .cl-hero__line:nth-child(3) { animation-delay: 0.18s; }
    .cl-hero__line:nth-child(4) { animation-delay: 0.27s; }
    .cl-hero__role    { animation: cl-rise 0.7s var(--ease-pop) 0.3s both; }
    .cl-hero__tagline { animation: cl-rise 0.7s var(--ease-pop) 0.38s both; }
    .cl-hero__cta     { animation: cl-rise 0.7s var(--ease-pop) 0.46s both; }
    .cl-hero__side    { animation: cl-rise 0.8s var(--ease-pop) 0.2s both; }

    /* Scroll-driven reveal, no JavaScript and no observer. Progressive: a
       browser without scroll timelines simply shows the cards, because the
       rule never applies. */
    @supports (animation-timeline: view()) {
        .cl-card,
        .cl-service,
        .cl-exp__row,
        .cl-recog__row {
            animation: cl-pop-in 1ms linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 22%;
        }
    }
}

/* -------------------------------------------------------------------------
   Narrower screens
   ------------------------------------------------------------------------- */
@media (max-width: 60rem) {
    .cl-hero__inner,
    .cl-about,
    .cl-track { grid-template-columns: minmax(0, 1fr); }

    /* The marks were placed in the gutter between the type and the portrait.
       One column means there is no gutter, and they end up sitting across the
       name instead of beside it. The framed portrait carries the colour here. */
    .cl-hero__deco { display: none; }

    /* One column now, so the name is measured against the full width. */
    .cl-hero__name { font-size: clamp(2.1rem, calc(110vw / var(--name-len, 8)), 5rem); }

    .cl-hero__side { max-width: 22rem; justify-self: start; }

    .cl-bar__nav { display: none; }
    .cl-bar__status { margin-left: auto; }
}

@media (max-width: 34rem) {
    .cl-bar__status { display: none; }

    /* The nav comes back on its own row rather than fighting the name for
       space on one line. */
    .cl-bar__inner { flex-wrap: wrap; gap: 0.5rem 0.8rem; }
    .cl-bar__nav {
        display: flex;
        gap: 0.9rem;
        width: 100%;
        margin-left: 0;
        padding-top: 0.15rem;
        border-top: 2px solid var(--ink);
        font-size: 0.7rem;
    }

    .cl-blob--1 { width: 5rem; height: 5rem; }
    .cl-blob--2 { width: 3.5rem; height: 3.5rem; }
    .cl-reg { width: 3rem; height: 3rem; }

    .cl-exp__row { grid-template-columns: minmax(0, 1fr); gap: 0.35rem; }
    .cl-swatches__grid { grid-template-columns: repeat(3, 1fr); }
    .cl-portrait::before { transform: translate(9px, 9px) rotate(2.5deg); }
    .cl-portrait::after  { transform: translate(-8px, 7px) rotate(-3deg); }
}

/* -------------------------------------------------------------------------
   Higher contrast
   ------------------------------------------------------------------------- */
@media (prefers-contrast: more) {
    .theme-chroma-lab { background-image: none; }
    .cl-hero__line:nth-child(even) { color: var(--ink); -webkit-text-stroke: 0; }
    .cl-reg { opacity: 1; }
}

/* Printing a portfolio is a real thing designers do. */
@media print {
    .cl-bar, .cl-ticker, .cl-hero__deco { display: none; }
    .theme-chroma-lab { background: #fff; background-image: none; }
    .cl-card, .cl-service { box-shadow: none; break-inside: avoid; }
}
