/* Arconcept Studio — portfolio
   Palette note: the brief specified #313131 as the page background, but the
   photography is dark, saturated neon; a mid grey flattens it. #313131 is kept
   for panels/cards and the base goes near-black so the images carry the page. */

:root {
    --bg: #0d0d0c;
    --panel: #313131;
    --panel-soft: #1a1a19;
    --accent: #aa8a56;
    --accent-lift: #c9a86c;
    --text: #e8e5e0;
    --muted: rgba(232, 229, 224, .68);
    --faint: rgba(232, 229, 224, .46);
    --line: rgba(232, 229, 224, .16);
    --ease: cubic-bezier(.22, 1, .36, 1);
    /* One deliberate type scale, all regular weight, so the page reads on a few
       sizes instead of a dozen: head (titles) → sub (names/subtitles) →
       body (copy) → label (small uppercase meta). */
    --fs-head: clamp(28px, 3.6vw, 52px);
    --fs-sub: clamp(16px, 1.7vw, 26px);
    --fs-body: clamp(14px, 1.05vw, 16px);
    --fs-label: 12px;
}

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

html { scroll-behavior: smooth; }

body {
    background: var(--bg);
    color: var(--text);
    font-family: Montserrat, system-ui, sans-serif;
    font-weight: 400;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

::selection { background: var(--accent); color: #000; }

/* Film grain — sits above everything, ignores pointer events. */
.grain {
    position: fixed;
    inset: -10%;
    z-index: 200;
    pointer-events: none;
    opacity: .04;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
    animation: grain .2s steps(1) infinite;
}

@keyframes grain {
    0% { transform: translate(0, 0); }
    25% { transform: translate(-2%, 1%); }
    50% { transform: translate(2%, -1%); }
    75% { transform: translate(-1%, -2%); }
}

/* ---------- shared type ---------- */

.eyebrow {
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--accent);
}

.h-sec {
    font-size: var(--fs-head);
    font-weight: 400;
    line-height: 1.08;
    letter-spacing: -.02em;
}

.h-sec em { font-style: normal; color: var(--accent); }

/* Per-line reveal: each line rises out from behind its own clip, staggered.
   Driven by the parent .reveal gaining .in on scroll. padding/margin give
   descenders room so the clip never shaves a "д"/"р" tail at rest. */
.line-rise .ln { display: block; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.line-rise .ln > * { display: inline-block; transform: translateY(115%); transition: transform 1s var(--ease); }
.line-rise .ln:nth-child(2) > * { transition-delay: .12s; }
.reveal.in .line-rise .ln > * { transform: none; }

.lede {
    font-size: var(--fs-body);
    line-height: 1.75;
    color: var(--muted);
    max-width: 62ch;
}

.wrap {
    max-width: 1560px;
    margin: 0 auto;
    padding: 0 clamp(20px, 4vw, 64px);
}

.section { padding: clamp(80px, 11vw, 170px) 0; }

/* ---------- reveal ---------- */

.reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .9s var(--ease), transform .9s var(--ease);
}

.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; transition: none; }
    .line-rise .ln > * { transform: none; transition: none; }
    .grain { animation: none; }
    html { scroll-behavior: auto; }
}

/* ---------- hero: tile menu ---------- */

/* The name is a full-bleed layer *under* the tile grid, not a cell inside it —
   the tiles are translucent, so it reads across the whole screen. */
.hero {
    position: relative;
    height: 100svh;
    min-height: 560px;
    padding: clamp(12px, 1.4vw, 20px);
    display: flex;
    flex-direction: column;
    gap: clamp(6px, .7vw, 10px);
}

/* ---------- floating glass header ----------
   Fixed, centred, frosted. Parked above the viewport over the hero and slid
   into place once the hero scrolls out (site.js toggles .on). */
.site-header {
    position: fixed;
    top: clamp(10px, 1.3vw, 18px);
    left: 50%;
    z-index: 100;
    width: min(1560px, calc(100% - clamp(24px, 4vw, 52px)));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 15px 15px 15px clamp(20px, 1.8vw, 30px);
    background: rgba(48, 48, 46, .42);
    -webkit-backdrop-filter: blur(24px);
    backdrop-filter: blur(24px);
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: 18px;
    transform: translate(-50%, calc(-100% - 24px));
    opacity: 0;
    pointer-events: none;
    transition: transform .6s var(--ease), opacity .45s var(--ease);
}

.site-header.on {
    transform: translate(-50%, 0);
    opacity: 1;
    pointer-events: auto;
}

.site-header__logo { display: flex; }
.site-header__logo .mark { width: 172px; }

.site-header__nav {
    display: flex;
    gap: clamp(18px, 2.2vw, 40px);
    font-size: clamp(13px, 1vw, 15px);
    letter-spacing: .01em;
}

.site-header__nav a { color: var(--muted); transition: color .35s var(--ease); }
.site-header__nav a:hover { color: var(--accent); }

.site-header__social {
    display: flex;
    gap: 10px;
}

.site-header__social a {
    width: 40px;
    height: 40px;
    display: grid;
    place-content: center;
    color: var(--muted);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 11px;
    transition: color .35s var(--ease), background .35s var(--ease), border-color .35s var(--ease);
}

.site-header__social a:hover { color: var(--text); border-color: rgba(255, 255, 255, .28); background: rgba(255, 255, 255, .06); }
.site-header__social svg { width: 18px; height: 18px; }

@media (max-width: 720px) {
    /* Drop nav labels on phones; keep logo + social, like the reference. */
    .site-header { gap: 12px; }
    .site-header__nav { display: none; }
    .site-header__logo .mark { width: 140px; }
}

@media (prefers-reduced-motion: reduce) {
    .site-header { transition: opacity .45s var(--ease); transform: translate(-50%, 0); }
}

.hero-grid {
    position: relative;
    z-index: 1;
    flex: 1;
    min-height: 0;
    display: grid;
    gap: clamp(6px, .7vw, 10px);
    grid-template-columns: 1fr 1.15fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-template-areas:
        "about work work"
        "team  team  social";
}

/* Tiles — frosted glass. The name is not blurred itself: each tile blurs
   whatever sits behind it, so the name reads sharp in the gaps between tiles
   and as a soft ghost underneath them. Same values as the reference. */
.tile {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: rgba(232, 229, 224, .04);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    display: flex;
    align-items: flex-end;
    padding: clamp(14px, 1.5vw, 24px);
    transition: background .5s var(--ease);
    /* Revealed bottom-up once the name has landed. */
    animation: tile-open .8s var(--ease) backwards;
    animation-delay: calc(var(--d, 0ms) + 1250ms);
}

.tile:hover { background: rgba(232, 229, 224, .075); }

/* Slides up as it is revealed. The clip alone was near-invisible: the panel is
   only 5.5% white on near-black, so uncovering it read as nothing happening. */
@keyframes tile-open {
    from {
        clip-path: inset(100% 0 0 0);
        transform: translateY(22%);
    }
}

.tile-label {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: baseline;
    gap: 12px;
    font-size: var(--fs-sub);
    font-weight: 400;
    letter-spacing: .04em;
    text-transform: uppercase;
    transition: transform .5s var(--ease);
}

.tile:hover .tile-label { transform: translateX(6px); }

/* Direct child only: the roll splits the label into nested <i> elements, and a
   descendant selector here would restyle every letter as the tile number. */
.tile-label > i {
    font-style: normal;
    font-size: var(--fs-label);
    letter-spacing: .16em;
    color: var(--accent);
}

.tile-label b { font-weight: 400; }

.tile--about  { grid-area: about; }
.tile--work   { grid-area: work; }
.tile--team   { grid-area: team; }
.tile--social { grid-area: social; }

/* Name layer: spans the whole hero, sits beneath the grid. */
.hero-title {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: grid;
    place-content: center;
    pointer-events: none;
    overflow: hidden;
    /* Shared by the name and the per-tile backdrop titles so they swap at
       exactly the same size. */
    --hero-type: clamp(40px, 8.5vw, 176px);
}

/* Pointer-tracked glow (yk-produce-ish), behind the name. */
.hero-title::after {
    content: "";
    position: absolute;
    width: 60vmax;
    height: 60vmax;
    left: var(--mx, 50%);
    top: var(--my, 50%);
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(170, 138, 86, .14) 0%, transparent 62%);
    pointer-events: none;
    opacity: 0;
    transition: opacity .8s var(--ease);
}

.hero:hover .hero-title::after { opacity: 1; }

.wordmark {
    position: relative;
    z-index: 1;
    /* Sized so the 9-char "ARCONCEPT" spans ~55% of the viewport and crosses
       several tiles, as in the reference. */
    font-size: var(--hero-type);
    /* Weight 400 on pure white, matching the reference. The body's 200 is
       hairline: at blur(16px) the strokes wash out to nothing, which is why
       this name has to be heavier than the rest of the page's type. */
    font-weight: 400;
    color: #fff;
    letter-spacing: -.03em;
    line-height: .9;
    /* Two stacked lines: "ARCONCEPT" over "studio". */
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    transition: opacity .4s var(--ease), transform .55s var(--ease);
}

/* Backdrop media — one layer per menu item, filling the hero behind the tiles.
   Faded in on hover (site.js) and read through the frosted tiles, so it lands
   as an atmospheric blur in the panels and sharp in the gaps between them. */
.hero-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    /* Kept a touch dark so the tile labels stay legible over it. */
    filter: brightness(.62) contrast(1.02);
    transition: opacity .7s var(--ease);
    pointer-events: none;
}

.hero-media.on { opacity: 1; }

/* Контакты backdrop is type, not a photo: our channels stacked top-to-bottom in
   the wordmark's face, read through the tiles the same way the name is. */
.hero-media--links {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(4px, 1vh, 16px);
    filter: none;
    font-weight: 400;
    font-size: clamp(30px, 6.6vw, 96px);
    line-height: 1;
    letter-spacing: -.02em;
    text-transform: uppercase;
    color: #fff;
}

.hero-media--links span:nth-child(even) { color: var(--accent-lift); }

/* When a media layer is up, dim the wordmark so the photo/video reads. "О студии"
   has no media, so hovering it never adds .has-media and the name stays. */
.hero-title.has-media .wordmark { opacity: .12; }
.hero-title.has-text .wordmark { opacity: 0; }

.wordmark .word {
    display: inline-flex;
    white-space: nowrap;
    font-weight: inherit;
}

.wordmark .thin { color: var(--accent-lift); }

.hero-foot {
    position: relative;
    z-index: 2;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 8px 2px;
    font-size: var(--fs-label);
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted);
}

.hero-foot a:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
}

/* ---------- about ---------- */

.about-grid {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    gap: clamp(32px, 5vw, 90px);
    align-items: start;
}

.stat-list { margin-top: 44px; border-top: 1px solid var(--line); }

.stat {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 20px;
    padding: 17px 0;
    border-bottom: 1px solid var(--line);
    font-size: var(--fs-body);
}

.stat dt { color: var(--faint); letter-spacing: .12em; text-transform: uppercase; font-size: var(--fs-label); }
.stat dd { color: var(--text); text-align: right; }

/* ---------- services accordion ----------
   Rows invert to light-on-dark when open (the dark-theme equivalent of the
   reference's black-on-paper), and the panel opens via a 0fr→1fr grid row so
   no JS height measurement is needed. */

.acc { display: grid; gap: 10px; }

/* Rounded frosted cards, spaced apart, per the brief. overflow clips the
   invert plaque (.acc-row::before) to the rounded corners. */
.acc-item {
    border: 1px solid var(--line);
    border-radius: 16px;
    overflow: hidden;
    background: rgba(232, 229, 224, .03);
    -webkit-backdrop-filter: blur(7px);
    backdrop-filter: blur(7px);
}

.acc-row {
    position: relative;
    width: 100%;
    display: grid;
    grid-template-columns: 56px 1fr 40px;
    align-items: center;
    gap: 14px;
    padding: clamp(18px, 2.4vw, 38px) clamp(14px, 1.6vw, 26px);
    text-align: left;
    transition: color .45s var(--ease);
}

/* Plaque wipes up from the bottom on hover (and stays for the open row), like
   the reference — the row inverts instead of just tinting. */
.acc-row::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--text);
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform .45s var(--ease);
    z-index: 0;
}

.acc-row:hover::before,
.acc-item.open .acc-row::before { transform: scaleY(1); }

.acc-n, .acc-t, .acc-x { position: relative; z-index: 1; }

.acc-row:hover, .acc-item.open .acc-row { color: var(--bg); }

.acc-n {
    font-size: var(--fs-label);
    letter-spacing: .14em;
    color: var(--accent);
    transition: color .45s var(--ease);
}

.acc-row:hover .acc-n,
.acc-item.open .acc-n { color: var(--bg); opacity: .55; }

.acc-t {
    font-size: var(--fs-sub);
    font-weight: 400;
    letter-spacing: .01em;
    line-height: 1.12;
    text-transform: uppercase;
}

/* Square button around the toggle, like the reference. The plus rotates into a
   minus when the row opens; currentColor keeps border and glyph inverting with
   the row (cream on the dark rows, dark on the open light plaque). */
.acc-x {
    justify-self: end;
    position: relative;
    width: 38px;
    height: 38px;
    border: 1px solid currentColor;
    border-radius: 8px;
    opacity: .85;
    transition: opacity .45s var(--ease);
}

.acc-x::before, .acc-x::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 13px;
    height: 1.5px;
    background: currentColor;
    transform: translate(-50%, -50%);
    transition: transform .45s var(--ease);
}

.acc-x::after { transform: translate(-50%, -50%) rotate(90deg); }
.acc-item.open .acc-x::after { transform: translate(-50%, -50%) rotate(0deg); }

.acc-p {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .55s var(--ease);
}

.acc-item.open .acc-p { grid-template-rows: 1fr; }

.acc-p > div { overflow: hidden; }

.acc-p p {
    padding: 20px clamp(12px, 1.4vw, 22px) 20px 70px;
    max-width: 74ch;
    font-size: var(--fs-body);
    line-height: 1.7;
    color: var(--muted);
}

/* Example work for each stage — a row of shots, aligned under the copy. */
.acc-examples {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(8px, 1vw, 14px);
    padding: 0 clamp(12px, 1.4vw, 22px) 28px 70px;
}

.acc-examples img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 10px;
}

@media (max-width: 720px) {
    .acc-row { grid-template-columns: 30px 1fr 34px; gap: 10px; }
    .acc-x { width: 34px; height: 34px; }
    .acc-p p, .acc-examples { padding-left: 42px; }
}

@media (prefers-reduced-motion: reduce) {
    .acc-p, .acc-row, .acc-row::before, .acc-x::before, .acc-x::after { transition: none; }
}

/* ---------- projects grid ---------- */

.rail-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 24px;
    margin-bottom: clamp(28px, 3.4vw, 52px);
}

.rail-nav { display: flex; gap: 8px; }

.pager-btn {
    width: 50px;
    height: 50px;
    border: 1px solid var(--line);
    display: grid;
    place-content: center;
    transition: border-color .4s var(--ease), background .4s var(--ease), opacity .3s;
}

.pager-btn:hover { border-color: var(--accent); background: rgba(170, 138, 86, .1); }
.pager-btn:disabled { opacity: .25; cursor: default; }
.pager-btn:disabled:hover { border-color: var(--line); background: none; }
.pager-btn svg { width: 16px; stroke: currentColor; fill: none; stroke-width: 1.8; }

.pgrid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(10px, 1.2vw, 20px);
}

.pcard {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--panel-soft);
    border-radius: 8px;
}

/* Full-card link — covers the image so the photo itself opens the project.
   Sits below the plate (z 3) and arrows (z 4), which stay independently clickable. */
.pcard-link { position: absolute; inset: 0; z-index: 2; }

/* Media zooms on hover; two stacked images let colour wipe in over the mono
   base from whichever edge the pointer entered (clip-path set by site.js). */
.pcard-media {
    position: absolute;
    inset: 0;
    transition: transform 1.1s var(--ease);
}

@media (hover: hover) {
    .pcard:hover .pcard-media { transform: scale(1.06); }
}

.pcard-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.pcard-img.base { filter: grayscale(1) contrast(1.05) brightness(.82); }

.pcard-img.color {
    clip-path: inset(0 100% 0 0);
    transition: clip-path .55s var(--ease);
}

.pcard::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(8, 8, 8, .55) 0%, transparent 44%);
    pointer-events: none;
}

/* Glass plate — a rounded frosted panel floating in the lower-right, inset from
   the card edges. It is the link to the project. */
.pcard-plate {
    position: absolute;
    z-index: 3;
    right: clamp(14px, 2.2%, 28px);
    bottom: clamp(14px, 2.6%, 32px);
    width: clamp(230px, 42%, 380px);
    min-height: clamp(170px, 44%, 260px);
    padding: clamp(18px, 2vw, 28px);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 18px;
    border-radius: 20px;
    background: rgba(28, 26, 25, .26);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, .14);
    transition: background .5s var(--ease), border-color .5s var(--ease);
}

.pcard-plate:hover { background: rgba(28, 26, 25, .14); border-color: rgba(255, 255, 255, .26); }

.pcard-fact .k { display: block; font-size: var(--fs-label); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.pcard-fact .v { display: block; font-size: var(--fs-body); color: var(--text); margin-top: 3px; }
.pcard-fact--year { align-self: flex-end; text-align: right; }

/* Bottom row: name pinned left, city pinned right. */
.pcard-plate-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; }
.pcard-plate-foot .pcard-fact { text-align: right; }

.pcard-name {
    font-size: var(--fs-sub);
    font-weight: 400;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* Carousel arrows — over the image, left of the plate; appear on hover. */
.pcard-nav {
    position: absolute;
    z-index: 4;
    left: clamp(14px, 1.6vw, 22px);
    bottom: clamp(14px, 1.6vw, 22px);
    display: flex;
    gap: 8px;
    opacity: 0;
    transition: opacity .4s var(--ease);
}

.pcard:hover .pcard-nav { opacity: 1; }

.pcard-nav button {
    width: 38px;
    height: 38px;
    display: grid;
    place-content: center;
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 50%;
    background: rgba(18, 18, 17, .3);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--text);
    transition: background .3s var(--ease), border-color .3s var(--ease);
}

.pcard-nav button:hover { background: rgba(18, 18, 17, .55); border-color: rgba(255, 255, 255, .4); }
.pcard-nav svg { width: 15px; stroke: currentColor; fill: none; stroke-width: 1.5; }

/* Not-yet-shot projects: blurred placeholder, per the brief's "coming soon" tile. */
.pcard--soon .pcard-img.base { filter: grayscale(.4) blur(24px) brightness(.55); transform: scale(1.15); }

.pcard-soon {
    position: absolute;
    z-index: 3;
    inset: auto 0 0 0;
    padding: clamp(18px, 2vw, 30px);
    font-size: var(--fs-label);
    letter-spacing: .26em;
    text-transform: uppercase;
    color: var(--text);
}

@media (max-width: 720px) {
    .pgrid { grid-template-columns: 1fr; }
    /* Plate becomes a compact bottom bar, hugging its content so the photo shows. */
    .pcard-plate { left: clamp(14px, 2.2%, 28px); width: auto; min-height: 0; }
    /* No hover on touch — keep the arrows reachable. Move them to the top so they
       never sit under the project name at the plate's bottom-left. */
    .pcard-nav { opacity: 1; top: clamp(12px, 3vw, 18px); bottom: auto; }
}

@media (prefers-reduced-motion: reduce) {
    .pcard-media, .pcard-img.color { transition: none; }
}

/* ---------- team ---------- */

.team-strip {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: clamp(6px, .8vw, 12px);
}

.face-media {
    position: relative;
    overflow: hidden;
    background: var(--panel);
    aspect-ratio: 3 / 4;
}

/* Two stacked portraits: mono base, colour on top revealed directionally by
   site.js (same mechanic as the project cards). */
.face-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
    transition: transform 1s var(--ease);
}

.face-img.base { filter: grayscale(1) contrast(1.05); }

.face-img.color {
    clip-path: inset(0 100% 0 0);
    transition: clip-path .55s var(--ease), transform 1s var(--ease);
}

@media (hover: hover) {
    .face:hover .face-img { transform: scale(1.05); }
}

/* Caption sits below the portrait (reference layout), not overlaid. */
.face figcaption {
    padding: 14px 2px 0;
}

.face-name {
    display: block;
    color: var(--text);
    font-weight: 400;
    font-size: var(--fs-body);
    letter-spacing: .01em;
}

.face-role {
    display: block;
    color: var(--muted);
    font-size: var(--fs-label);
    margin-top: 3px;
    line-height: 1.35;
}

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

/* ---------- contacts ---------- */

.contact { border-top: 1px solid var(--line); }

/* Compact channel picker — one row of rounded frosted tiles, matching the
   accordion cards and header glass. */
.contact-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: clamp(10px, 1.2vw, 18px);
}

.c-tile {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: clamp(18px, 1.8vw, 30px);
    border: 1px solid var(--line);
    border-radius: 16px;
    background: rgba(232, 229, 224, .03);
    -webkit-backdrop-filter: blur(7px);
    backdrop-filter: blur(7px);
    transition: background .4s var(--ease), border-color .4s var(--ease), transform .4s var(--ease);
}

.c-tile:hover {
    background: rgba(232, 229, 224, .06);
    border-color: rgba(255, 255, 255, .28);
    transform: translateY(-3px);
}

.c-tile__name {
    font-size: var(--fs-sub);
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--text);
}

.c-tile__name::after { content: " →"; color: var(--accent); }

.c-tile__handle {
    font-size: var(--fs-body);
    color: var(--muted);
    word-break: break-word;
}

@media (max-width: 720px) {
    .contact-row { grid-template-columns: repeat(2, 1fr); gap: 10px; }
    .c-tile { padding: clamp(14px, 3.5vw, 20px); gap: 7px; }
    .c-tile__name { font-size: 15px; }
    /* Handles are long single tokens; smaller so they wrap cleanly in a narrow tile. */
    .c-tile__handle { font-size: 12px; line-height: 1.35; }
}

/* ---------- per-letter roll ----------
   Each character is a clipping box holding two stacked copies: the resting one
   rolls out the top while its duplicate arrives from the bottom, staggered by
   --i so the word wipes left-to-right. Shared by the contact list and the hero
   tiles — same mechanic the reference uses in both places.
   --i: char index (set per box in JS). --d: per-element head start (set in HTML). */

.roll { display: inline-flex; }

.roll-ch {
    display: inline-block;
    position: relative;
    overflow: hidden;
    /* Box height == letter box height, so translateY(100%) clears it exactly.
       Any mismatch (e.g. padding for descenders) leaves a sliver of the
       incoming copy peeking out at rest. The 1.25 also gives g/у/р their tails. */
    line-height: 1.25;
}

.roll-ch i {
    display: block;
    font-style: normal;
    transition: transform .5s var(--ease);
    transition-delay: calc(var(--i) * 26ms + var(--d, 0ms));
}

.roll-ch i + i {
    position: absolute;
    left: 0;
    top: 0;
    transform: translateY(100%);
}

.tile:hover .roll-ch i { transform: translateY(-100%); }

.tile:hover .roll-ch i + i { transform: translateY(0); }

/* Intro: the resting copy starts below its clip box and rises into place, the
   same move the reference plays on load.
   A keyframe animation, not a JS-toggled class: rAF does not fire in a
   background tab, so a class-swap approach leaves the hero blank until the tab
   is focused. `backwards` holds the offscreen start during the delay, and with
   no fill the letters revert to the base transform afterwards, leaving the
   hover roll free to take over. */
/* Sequence, per the reference: the company name lands first, the menu follows.
   Tiles open at 1250ms (see .tile), so their labels come after that. */
.wordmark .roll-ch i:first-child {
    animation: rise .9s var(--ease) backwards;
    animation-delay: calc(var(--i) * 30ms + 220ms);
}

.tile .roll-ch i:first-child {
    animation: rise .7s var(--ease) backwards;
    animation-delay: calc(var(--i) * 22ms + var(--d, 0ms) + 1500ms);
}

@keyframes rise {
    from { transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
    .roll-ch i { transition: none; }
    .tile:hover .roll-ch i { transform: none; }
    .tile:hover .roll-ch i + i { opacity: 0; }
    .wordmark .roll-ch i:first-child,
    .tile .roll-ch i:first-child { animation: none; }
    .tile { animation: none; }
}

.foot {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 40px 0;
    font-size: var(--fs-label);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--faint);
    flex-wrap: wrap;
}

/* ---------- project page ---------- */

/* Split project layout: sticky info rail on the left, scrolling gallery right.
   Top padding clears the fixed glass header. */
.p-split {
    max-width: 1600px;
    margin: 0 auto;
    padding: clamp(96px, 13vh, 150px) clamp(20px, 4vw, 64px) clamp(50px, 7vw, 100px);
    display: grid;
    grid-template-columns: minmax(300px, 34%) 1fr;
    gap: clamp(28px, 3.4vw, 64px);
    align-items: start;
}

.p-info { position: sticky; top: clamp(96px, 12vh, 130px); }

.p-back {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: var(--fs-label);
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--muted);
    transition: color .35s var(--ease);
}
.p-back:hover { color: var(--accent); }
.p-back-ic { transition: transform .35s var(--ease); }
.p-back:hover .p-back-ic { transform: translateX(-3px); }

.p-title { font-size: var(--fs-head); font-weight: 400; letter-spacing: -.02em; line-height: 1.06; }

/* Facts as bracketed chips, like the reference. */
.p-chips { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 22px; }
.p-chip { font-size: var(--fs-label); letter-spacing: .06em; color: var(--muted); }
.p-chip::before { content: "[ "; color: var(--accent); }
.p-chip::after { content: " ]"; color: var(--accent); }

.p-gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(8px, 1vw, 16px); }
.p-gallery figure { position: relative; overflow: hidden; background: var(--panel-soft); aspect-ratio: 4 / 3; border-radius: 10px; }
.p-gallery figure.full { grid-column: 1 / -1; aspect-ratio: 16 / 9; }

@media (max-width: 900px) {
    .p-split { grid-template-columns: 1fr; gap: clamp(28px, 6vw, 48px); }
    .p-info { position: static; }
    .p-gallery figure.full { grid-column: auto; aspect-ratio: 4 / 3; }
}

/* Lightbox — enlarge a gallery photo (tap/click), with prev/next + close. */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 300;
    display: none;
    place-items: center;
    background: rgba(8, 8, 8, .93);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.lightbox.open { display: grid; }

/* Project caption, top-left — balances the close button and keeps the open
   photo labelled. */
.lb-title {
    position: absolute;
    top: clamp(18px, 3vw, 34px);
    left: clamp(18px, 3vw, 40px);
    z-index: 4;
    display: flex;
    flex-direction: column;
    gap: 4px;
    text-shadow: 0 2px 18px rgba(0, 0, 0, .6);
}
.lb-title-k { font-size: var(--fs-label); letter-spacing: .22em; text-transform: uppercase; color: var(--accent); }
.lb-title-n { font-size: var(--fs-sub); letter-spacing: .01em; color: var(--text); }

/* Fixed-size stage holds both layers so they occupy the same box; each image is
   object-fit: contain and centres within it regardless of aspect. */
.lb-stage { position: relative; width: 92vw; height: 86vh; }

.lb-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* Opaque backdrop colour so the incoming layer fully covers the outgoing one
       as it wipes — no old photo bleeding through the letterbox margins. */
    background: #080808;
    /* The incoming layer starts clipped to an edge and wipes open (set in JS). */
    clip-path: inset(0 0 0 0);
}

.lb-btn {
    position: absolute;
    display: grid;
    place-content: center;
    width: 48px;
    height: 48px;
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 50%;
    background: rgba(18, 18, 17, .4);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--text);
    transition: background .3s var(--ease), border-color .3s var(--ease);
}
.lb-btn:hover { background: rgba(18, 18, 17, .7); border-color: rgba(255, 255, 255, .4); }
.lb-btn svg { width: 18px; stroke: currentColor; fill: none; stroke-width: 1.6; }

.lb-close { top: clamp(16px, 3vw, 28px); right: clamp(16px, 3vw, 28px); }
.lb-prev { left: clamp(12px, 2vw, 28px); top: 50%; transform: translateY(-50%); }
.lb-next { right: clamp(12px, 2vw, 28px); top: 50%; transform: translateY(-50%); }

.lb-count {
    position: absolute;
    bottom: clamp(16px, 3vw, 28px);
    left: 50%;
    transform: translateX(-50%);
    font-size: var(--fs-label);
    letter-spacing: .14em;
    color: var(--text);
}

/* Two stacked images (mono base + colour), reused by the next-project tile. */
.gal-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 1.1s var(--ease);
}
/* Project-page photos are full colour by default (per the brief). The colour
   layer stays for the next-project tile's hover reveal, but the base is no
   longer desaturated, so the galleries read in colour without a hover. */
.gal-img.base { filter: none; }
.gal-img.color { clip-path: inset(0 100% 0 0); transition: clip-path .55s var(--ease), transform 1.1s var(--ease); }

@media (hover: hover) {
    .p-gallery figure:hover .gal-img,
    .p-next:hover .gal-img { transform: scale(1.03); }
}

/* Next project — a full-bleed image tile that echoes the project cards. */
.p-next {
    position: relative;
    display: block;
    overflow: hidden;
    height: clamp(150px, 21vh, 260px);
    margin-top: clamp(40px, 5vw, 80px);
    background: var(--panel-soft);
    border-radius: 14px;
}

.p-next-media { position: absolute; inset: 0; }

.p-next::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(8, 8, 8, .78) 0%, transparent 60%);
    pointer-events: none;
}

.p-next-plate {
    position: absolute;
    z-index: 2;
    inset: auto 0 0 0;
    padding: clamp(24px, 4vw, 64px);
    text-shadow: 0 2px 24px rgba(0, 0, 0, .55);
}

/* Larger, brighter than the page eyebrows — these read over a photo. */
.p-next-plate .eyebrow { font-size: 15px; color: var(--accent-lift); }

.p-next b {
    display: block;
    margin: 10px 0 10px;
    font-size: var(--fs-head);
    font-weight: 400;
    letter-spacing: -.02em;
    line-height: 1;
    transition: color .4s var(--ease);
}
.p-next:hover b { color: var(--accent-lift); }

.p-next-go {
    font-size: 16px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text);
}

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

/* ---------- responsive ---------- */

@media (max-width: 1100px) {
    .about-grid { grid-template-columns: 1fr; }
    .team-strip { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 720px) {
    /* Tiles stack; the name still spans behind them rather than taking a row. */
    .hero-grid {
        grid-template-columns: 1fr;
        grid-template-rows: repeat(4, 1fr);
        grid-template-areas: "about" "work" "team" "social";
    }

    /* Name stays centred and crosses the stacked tiles, as in the reference's
       phone mock — it is blurred and the labels paint over it, so an overlap
       reads as intended rather than as a collision. */
    /* Centred behind the stacked tiles, as before — just a touch smaller. */
    .hero-title { --hero-type: clamp(34px, 11vw, 72px); }
    /* No hover on touch, so the backdrop media would never come back. */
    .hero-media { display: none; }

    .hero-foot { flex-direction: column; gap: 8px; align-items: flex-start; }
    .team-strip { grid-template-columns: repeat(2, 1fr); }
}
