/* madd. website, shared by /en/ and /ro/.
   Values come from docs/design-tokens.md (Figma file MAIN). Figma only has 1440px desktop frames.

   Breakpoints
     1280px and up   desktop, as in Figma
     768 to 1279px   tablet: desktop layouts, type and gaps scale down. Under 1024px a few
                     rows restack because the three column rows get too narrow.
     under 768px     phone: one column, no pinning */

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-var-latin.woff2") format("woff2");
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Neutral ramp (Figma _colors, first column). Names are proposed, not Figma's. */
  --neutral-0: #fffcf2;
  --neutral-100: #e8e5dc;
  --neutral-200: #cfcdc5;
  --neutral-300: #b8b6af;
  --neutral-400: #a09e98;
  --neutral-500: #888681;
  --neutral-600: #706f6b;
  --neutral-700: #595855;
  --neutral-800: #41403e;
  --neutral-900: #292928;
  --neutral-1000: #111111;

  /* Orange ramp step 600 (Figma _colors), used for form errors */
  --orange-600: #c44a1e;

  /* Roles */
  --bg: var(--neutral-0);
  --surface: var(--neutral-100);
  --ink: var(--neutral-1000);
  --text: var(--neutral-900);
  --muted: var(--neutral-600);
  --muted-strong: var(--neutral-800);

  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* One Figma pixel. 1px from 1440 up, shrinks with the screen below. Gaps are written as N * var(--s). */
  --s: min(1px, 100vw / 1440);

  /* Grid: 12 columns, 100px columns, 16px gutters and 32px margins at 1440 */
  --page-max: 1440px;
  --margin: clamp(24px, 3vw, 32px);
  --gutter: clamp(12px, 1.25vw, 16px);

  --radius-s: 8px;
  --radius-m: 16px;

  /* Type. All of these equal the Figma value from 1280 up. */
  --display: min(128px, 8.889vw);
  --h3: clamp(24px, 2.6563vw, 34px);
  --name: clamp(22px, 2.1875vw, 28px);
  --copy: clamp(16px, 1.5625vw, 20px);
  --copy-lh: clamp(23px, 1.875vw, 24px);

  /* Two lines every sticky thing on the page lines up with (change round 1), measured from the top of the viewport.
     --title-top: where the hero headline and every sticky section title sit, below the navbar.
     --content-top: where sticky images, names and text blocks sit, and where the triggers fire. Read by js/site.js. */
  --title-top: max(calc(162 * var(--s)), 112px);
  --content-top: clamp(120px, 24svh, 260px);

  /* Vertical rhythm measured in _full_preview */
  --hero-pad-top: var(--title-top);
  --gap-work-top: calc(110 * var(--s));
  --gap-work-title: calc(203 * var(--s));
  --gap-services-top: calc(236 * var(--s));
  --gap-services-title: calc(265 * var(--s));
  --gap-pillar: calc(200 * var(--s));
  --gap-studio-top: calc(204 * var(--s));
  --gap-studio-title: calc(199 * var(--s));
  --gap-profile-first: calc(200 * var(--s));
  --gap-profile: calc(400 * var(--s));
  --gap-contact-top: calc(404 * var(--s));
  --gap-footer: calc(219 * var(--s)); /* a third of Figma's 656, change round 2 */
  --bar-h: 64px; /* phone header bar */
}

@media (max-width: 767px) {
  :root {
    --margin: 16px;
    --gutter: 16px;

    --display: clamp(44px, 17vw, 72px);
    --h3: clamp(26px, 7.5vw, 34px);
    --name: 26px;
    --copy: 18px;
    --copy-lh: 25px;

    --title-top: 80px; /* just below the 64px phone bar */
    --content-top: 120px;

    --gap-work-top: 96px;
    --gap-work-title: 32px;
    --gap-services-top: 96px;
    --gap-services-title: 32px;
    --gap-pillar: 56px;
    --gap-studio-top: 96px;
    --gap-studio-title: 32px;
    --gap-profile-first: 56px;
    --gap-profile: 72px;
    --gap-contact-top: 96px;
    --gap-footer: 32px;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

html.nav-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
p,
ul,
figure,
address {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

a {
  color: inherit;
}

img {
  display: block;
  max-width: 100%;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* Tabbing must never leave the focused element hidden behind the fixed navbar pill */
a,
button,
input,
textarea {
  scroll-margin-top: 120px;
  scroll-margin-bottom: 24px;
}

main:focus {
  outline: none;
}

.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 110;
  padding: 12px 16px;
  border-radius: var(--radius-s);
  background: var(--ink);
  color: var(--neutral-0);
  font-size: 16px;
  line-height: 20px;
  text-decoration: none;
  transform: translateY(-200%);
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Layout ---------- */

.wrap {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--margin);
}

/* ---------- Shared type ---------- */

.section-title {
  grid-column: 1 / -1;
  max-width: var(--title-w, 4.41em); /* 564px at 1440: breaks the lines as in Figma at every size */
  color: var(--ink);
  font-size: var(--display);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
}

/* Section titles pin at --title-top while the section body scrolls over them. The body has the page background and a
   higher layer, so the title is covered, never shows through, and is gone once the body has passed.
   The title is a direct child of its section so the whole section is its range. Contact is not sticky. */
.section > .section-title,
.section > .section__head {
  position: sticky;
  top: var(--title-top);
  margin-inline: max(var(--margin), calc((100% - var(--page-max)) / 2 + var(--margin)));
}

/* Services: the title and its intro line pin together, so the image frame covers both. The line keeps a little inside
   the title's width (4.41 x --display), which is the frame's width. */
.section__intro {
  max-width: calc(4.3 * var(--display));
  margin-top: max(12px, calc(24 * var(--s)));
}

.section__body {
  position: relative;
  z-index: 1;
  background: var(--bg);
}

.item-title {
  color: var(--ink);
  font-size: var(--h3);
  font-weight: 600;
  line-height: 1.2;
}

.copy {
  color: var(--text);
  font-size: var(--copy);
  font-weight: 500;
  line-height: var(--copy-lh);
}

.copy + .copy {
  margin-top: var(--copy-lh);
}

.tags {
  margin-top: 12px;
  color: var(--muted);
  font-size: 16px;
  font-weight: 400;
  line-height: 27px;
}

/* ---------- Media placeholders ---------- */

.media {
  overflow: hidden;
  border-radius: var(--radius-s);
  background: var(--surface);
}

.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 147px;
  height: 35px;
  padding: 0 24px;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--neutral-900);
  color: var(--neutral-0);
  font: inherit;
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.btn {
  transition: background-color 150ms ease;
}

.btn:hover:not(:disabled) {
  background: var(--neutral-1000);
}

.btn:disabled {
  background: var(--neutral-200);
  color: var(--neutral-100);
  cursor: not-allowed;
}

/* ---------- Navbar ---------- */

/* The logo is fixed, above everything, and inverts against what is under it: white with mix-blend-mode difference
   reads dark on the cream page and light on dark images. It sits in the header (a landmark), which must stay
   unstyled: a parent stacking context (position, z-index, transform, filter, opacity, isolation) would cut the blend
   off. npm run check guards this. Padding and negative margin give a
   44px tall hit area without moving the logo. */
.logo {
  position: fixed;
  top: 45.5px;
  left: max(calc(var(--margin) + 8px), calc(50% - 680px));
  z-index: 100;
  display: block;
  padding: 10px 8px;
  margin: -10px -8px;
  line-height: 0;
  mix-blend-mode: difference;
}

.logo img {
  width: 91px;
  height: 24px;
  filter: brightness(0) invert(1);
}

.nav {
  position: fixed;
  top: 32px;
  right: 0;
  left: 0;
  z-index: 10;
  display: flex;
  justify-content: flex-end;
  padding-inline: max(var(--margin), calc(50% - 688px));
  pointer-events: none;
}

.nav__pill {
  display: flex;
  align-items: center;
  gap: 48px;
  padding: 8px;
  border-radius: var(--radius-m);
  background: var(--neutral-0);
  pointer-events: auto;
}

.nav__links {
  display: flex;
  gap: 48.5px;
  padding-left: 16px;
}

.nav__links a {
  color: var(--text);
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
}

.nav__links a:hover,
.nav__links a[aria-current="true"] { /* the section in view, set by js/site.js */
  text-decoration: underline;
  text-underline-offset: 4px;
}

.nav__toggle {
  display: none;
}

/* ---------- Hero ---------- */

.hero {
  min-height: calc(810 * var(--s));
}

.hero .wrap {
  align-items: start;
  padding-top: var(--hero-pad-top);
}

.hero__title {
  grid-column: 1 / 8; /* the four lines are set with <br> in the markup, as in Figma */
  color: var(--ink);
  font-size: var(--display);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
}

.hero__stage {
  position: relative;
}

/* The slot holds the state 1 box in the grid. The visual fills it, or is clipped out of it when the hero zooms. */
.hero__slot {
  position: relative;
  grid-column: 8 / 13;
  aspect-ratio: 1;
}

.hero__visual {
  position: absolute;
  inset: 0;
}

/* The still: the poster until the showreel plays (the video fades in over it), and what shows with reduced motion */
.hero__still {
  position: absolute;
  inset: 0;
}

/* Vimeo background player (hero showreel, Valuri loop), added by js/site.js. Sized like object-fit: cover for a 16:9
   video, centred, over whatever still sits in the box. */
[data-video] {
  container-type: size; /* the video covers whatever size the box has: 100cqw and 100cqh below */
}

:where([data-video]) {
  position: relative; /* no weight, so the hero box keeps its own position */
}

.media__video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(max(100cqw, 100cqh * 16 / 9) + 2px); /* a pixel past each edge, so no sliver of the still shows */
  height: calc(max(100cqh, 100cqw * 9 / 16) + 2px);
  border: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0; /* the still shows until the player reports that it plays (js/site.js) */
  transition: opacity 400ms ease-out;
}

.media__video.is-playing {
  opacity: 1;
}

/* ---------- Work ---------- */

#work {
  padding-top: var(--gap-work-top);
}

#work .section-title {
  margin-bottom: var(--gap-work-title);
}

/* "Proiectele" is wider than the 4.41em that fits every English title, so this one gets a wider box */
html[lang="ro"] #work .section-title {
  --title-w: 5.2em;
}

.collage {
  grid-column: 1 / 9;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gutter);
}

.collage__wide {
  grid-column: 1 / -1;
  aspect-ratio: 912 / 514;
}

.collage__tall {
  position: relative;
  grid-row: span 2;
}

.collage__tall img {
  position: absolute; /* the two small images set the row heights, the tall one fills them */
  inset: 0;
}

.collage__small {
  aspect-ratio: 448 / 257;
}

.project {
  grid-column: 9 / 13;
}

.project .item-title {
  margin-bottom: 16px;
}

/* ---------- Services ---------- */

#services {
  padding-top: var(--gap-services-top);
}

/* The space under the title is padding on the body, not a margin on the title: a sticky title keeps its margin inside
   the section, so a margin would make it leave early, while the image frame still covers only part of it */
#services .section__body {
  padding-top: var(--gap-services-title);
}

/* Pillars and profiles. Without JavaScript they are stacked rows: image, name, text. With JavaScript (.is-stacked,
   see "Stacks" at the end of this file) the image and name move into a sticky layer and only the text scrolls. */
.pillar,
.profile {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: start;
}

.stack:not(.is-stacked) {
  display: block; /* .wrap makes it a grid, that is only wanted once it is stacked */
}

.pillar + .pillar {
  margin-top: var(--gap-pillar);
}

.pillar__image {
  grid-column: 1 / 6;
  aspect-ratio: 564 / 457;
}

.pillar__name {
  grid-column: 6 / 9;
}

.pillar__body {
  grid-column: 9 / 13;
}

/* ---------- Studio ---------- */

#studio {
  padding-top: var(--gap-studio-top);
}

#studio .section-title {
  margin-bottom: var(--gap-studio-title);
}

.studio__image {
  grid-column: 1 / 9;
  aspect-ratio: 912 / 514;
}

.studio__text {
  grid-column: 9 / 13;
}

.studio__row {
  align-items: start;
}

#studio-stack {
  margin-top: var(--gap-profile-first);
}

.profile + .profile {
  margin-top: var(--gap-profile);
}

/* Name and role on the left, the portrait in the centre, bio and tags on the right (03_wireframes_profile_page_madd.pdf) */
.profile__who {
  grid-column: 3 / 6;
  grid-row: 1;
}

.profile__name {
  color: var(--ink);
  font-size: var(--name);
  font-weight: 600;
  line-height: 1.2;
}

.profile__role {
  margin-top: 4px;
  color: var(--text);
  font-size: 16px;
  line-height: 1.2;
}

.profile__photo {
  grid-column: 6 / 9;
  grid-row: 1;
  aspect-ratio: 332 / 457;
}

.profile__photo img {
  object-position: 50% 25%;
}

.profile__body {
  grid-column: 9 / 13;
  grid-row: 1;
}

/* ---------- Contact ---------- */

#contact {
  padding-top: var(--gap-contact-top);
}

#contact .wrap {
  align-items: start;
}

.contact__intro {
  grid-column: 1 / 7;
}

.contact__intro .section-title {
  margin-bottom: 22px;
}

.contact__email {
  display: block;
  width: fit-content;
  font-size: var(--copy);
  font-weight: 600;
  line-height: 24px;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

.contact__place {
  margin-top: 16px;
  font-size: var(--copy);
  font-weight: 600;
  line-height: 24px;
}

.form {
  grid-column: 7 / 11;
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: 560px;
  margin-top: -4px; /* Figma: form frame sits 5px above the title box */
  padding: 9px;
  border-radius: var(--radius-m);
  box-shadow: 0 0 0 1px var(--neutral-900); /* Figma strokes this frame outside, 450px outer width */
}

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

.form__field--grow {
  flex: 1;
}

.form__label {
  font-size: var(--copy);
  font-weight: 600;
  line-height: 24px;
}

.form__input {
  width: 100%;
  height: 35px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--radius-s);
  background: var(--neutral-900);
  color: var(--neutral-0);
  font: inherit;
  font-size: 16px;
  line-height: 35px;
}

.form__input::placeholder {
  color: var(--neutral-400); /* Figma uses neutral-700 (2.05:1), neutral-400 passes AA on the dark field */
  opacity: 1;
}

.form__input--area {
  flex: 1;
  min-height: 73px;
  padding-block: 8px;
  line-height: 24px;
  resize: none;
}

.form .btn {
  width: 100%;
}

/* Under the Send button: what we do with the details, with a link to the Privacy Policy (no checkbox) */
.form__notice {
  margin-top: -12px; /* closer to the button than the form's 24px gap */
  color: var(--muted);
  font-size: 14px;
  line-height: 20px;
}

.form__notice a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Honeypot: off screen, not display: none, and out of the tab order */
.form__bot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form__input[aria-invalid="true"] {
  outline: 2px solid var(--orange-600);
}

.form__error {
  color: var(--orange-600);
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
}

.form__message {
  display: none;
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
}

.form__message--success {
  color: var(--ink);
}

.form__message--error {
  color: var(--orange-600);
}

/* .is-visible comes from site.js. :target shows the thank you after the no-JavaScript redirect to #form-sent */
.form__message.is-visible,
.form__message:target {
  display: block;
}

/* ---------- Footer ---------- */

.site-footer {
  margin-top: var(--gap-footer);
  padding-bottom: 30px;
  color: var(--muted-strong);
}

/* Footer layout from 06_wireframes_contact_section_madd_footer_reference.pdf: the footer line on its own row (no longer struck through, round 7),
   then email/phone/city, the links, and the game side by side. Wraps on its own when there is no room (tablets). */
@media (min-width: 768px) {
  .site-footer .wrap {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: calc(64 * var(--s));
    row-gap: 32px;
  }
}

.footer__wink {
  flex: 0 0 100%;
  grid-column: 1 / -1;
  margin-bottom: -25px; /* row gap 32px minus the 7px of the design */
  font-size: var(--copy);
  font-weight: 600;
  line-height: 24px;
}

.footer__info,
.footer__links {
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  white-space: nowrap;
}

.footer__info li + li,
.footer__links li + li {
  margin-top: 4px;
}

.footer__info a,
.footer__links a {
  text-decoration: none;
}

.footer__info a:hover,
.footer__links a:hover {
  text-decoration: underline;
}

.footer__game {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px;
  margin-left: calc(120 * var(--s));
}

.wordsearch {
  display: grid;
  flex: none;
  grid-template-columns: repeat(5, 16px);
  gap: 4px;
  width: 130px;
  height: 130px;
  padding: 17px;
  border-radius: var(--radius-m);
  box-shadow: 0 0 0 1px var(--neutral-800);
  touch-action: none; /* a drag across the letters must not scroll the page */
  user-select: none;
}

/* Figma _game cell states: default, hover (darker letter), selected or found (dark fill) */
.wordsearch__cell {
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--neutral-100);
  color: var(--neutral-700); /* Figma: neutral-600 (4.0:1), neutral-700 passes AA */
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
}

button.wordsearch__cell {
  cursor: pointer;
}

button.wordsearch__cell:hover {
  color: var(--neutral-900);
}

/* Figma sets the letter on the dark fill in neutral-600 (2.9:1), neutral-100 is readable */
button.wordsearch__cell.is-start,
button.wordsearch__cell.is-found,
button.wordsearch__cell.is-start:hover,
button.wordsearch__cell.is-found:hover {
  background: var(--neutral-900);
  color: var(--neutral-100); /* stays light on hover, the hover colour is dark */
}

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

.wordsearch__info {
  color: var(--muted);
  font-size: 14px;
  font-weight: 300;
  line-height: 21px;
  text-align: center;
}

.wordsearch__list li.is-found {
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
}

/* Language switch: the current language is marked */
.footer__links a[aria-current] {
  color: var(--ink);
  font-weight: 600;
}

/* ---------- Privacy Policy pages ---------- */

.site-footer--compact {
  margin-top: 120px;
}

.legal {
  padding-top: 164px;
}

.legal__title {
  grid-column: 1 / -1;
  margin-bottom: 16px;
  color: var(--ink);
  font-size: clamp(30px, 8.6vw, 72px); /* "Politica de confidențialitate" must fit one word per line */
  font-weight: 600;
  line-height: 1.05;
}

.legal__updated {
  grid-column: 1 / -1;
  margin-bottom: 48px;
  font-size: 16px;
}

.legal__body {
  grid-column: 1 / 10;
  font-size: 16px;
  line-height: 1.6;
}

.legal__body h2 {
  margin: 48px 0 12px;
  color: var(--ink);
  font-size: var(--name);
  font-weight: 600;
  line-height: 1.2;
}

.legal__body p + p,
.legal__body p + ul,
.legal__body ul + p {
  margin-top: 12px;
}

.legal__body ul {
  padding-left: 1.25em;
  list-style: disc;
}

.legal__body li + li {
  margin-top: 4px;
}

.legal__body table {
  width: 100%;
  margin: 12px 0;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 1.5;
}

.legal__body th,
.legal__body td {
  padding: 12px 16px 12px 0;
  border-bottom: 1px solid var(--neutral-200);
  text-align: left;
  vertical-align: top;
}

.legal__body th {
  color: var(--ink);
  font-weight: 600;
}

.legal__body a {
  text-underline-offset: 3px;
}

/* Visible TODO from the draft: the [brackets] stay on the page until someone fills them in */
.todo {
  padding: 0 0.25em;
  border-radius: 4px;
  background: var(--neutral-100);
}

/* ---------- 404 pages ---------- */

.notfound {
  display: grid;
  align-content: center;
  min-height: 100vh;
  min-height: 100svh;
  padding-block: 120px 64px;
}

.notfound__code {
  grid-column: 1 / -1;
  color: var(--ink);
  font-size: var(--display);
  font-weight: 600;
  line-height: 1;
}

.notfound__text {
  grid-column: 1 / -1;
  margin-top: 24px;
  font-size: var(--copy);
  font-weight: 500;
  line-height: var(--copy-lh);
}

.notfound__link {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  width: fit-content;
  min-height: 44px;
  margin-top: 24px;
}

.notfound__text a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
}

/* ---------- Tablet, narrow (768 to 1023px) ----------
   Three column rows are too tight here, so image and text keep their order
   but the name and the text share one wider column. */

@media (min-width: 768px) and (max-width: 1023px) {
  /* The photo or image spans both rows, so the second row takes the slack and the text stays together */
  .pillar,
  .profile {
    grid-template-rows: auto 1fr;
  }

  .collage {
    grid-column: 1 / 8;
  }

  .project {
    grid-column: 8 / 13;
  }

  .pillar__image {
    grid-column: 1 / 6;
    grid-row: 1 / 3;
  }

  .pillar__name {
    grid-column: 6 / 13;
    grid-row: 1;
  }

  .pillar__body {
    grid-column: 6 / 13;
    grid-row: 2;
    margin-top: 12px;
  }

  .studio__image {
    grid-column: 1 / 8;
  }

  .studio__text {
    grid-column: 8 / 13;
  }

  .profile__photo {
    grid-column: 1 / 6;
    grid-row: 1 / 3;
  }

  .profile__who {
    grid-column: 6 / 13;
    grid-row: 1;
  }

  .profile__body {
    grid-column: 6 / 13;
    grid-row: 2;
    margin-top: 16px;
  }

  .contact__intro {
    grid-column: 1 / -1;
    margin-bottom: 48px;
  }

  .legal__body {
    grid-column: 1 / -1;
  }

  .form {
    grid-column: 1 / 9;
    height: auto;
    margin-top: 0;
  }

  .form__field--grow {
    flex: none;
  }

  .form__input--area {
    flex: none;
    min-height: 160px;
  }

}

/* ---------- Tablet, wide (1024 to 1279px) ---------- */

@media (min-width: 1024px) and (max-width: 1279px) {
  .nav__links,
  .nav__pill {
    gap: clamp(28px, 3.8vw, 48px);
  }

  .footer__game {
    gap: 16px;
  }
}

/* Under 1024px the game takes its own row */
@media (min-width: 768px) and (max-width: 1023px) {
  .footer__game {
    flex: 0 0 100%;
    margin-left: 0;
  }
}

/* ---------- Touch targets: 44px minimum below 1280px and on touch screens ---------- */

@media (max-width: 1279px), (pointer: coarse) {
  .btn {
    height: 44px;
  }

  .nav__links a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }

  .form__input {
    height: 44px;
    line-height: 44px;
  }

  .contact__email {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  .footer__info li,
  .footer__links li {
    display: flex;
    align-items: center;
    gap: 0.3em; /* keeps the spaces around the slash in "RO / EN" */
    min-height: 44px;
  }

  .footer__info li + li,
  .footer__links li + li {
    margin-top: 0;
  }

  /* Side padding with an equal negative margin widens the hit area of short links like "RO" without moving the text */
  .footer__info a,
  .footer__links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: 13px;
    margin-inline: -13px;
  }
}

/* ---------- Word search on touch screens and phones: 44px cells ---------- */

@media (pointer: coarse), (max-width: 767px) {
  .wordsearch {
    grid-template-columns: repeat(5, 44px);
    width: auto;
    height: auto;
  }

  .wordsearch__cell {
    width: 44px;
    height: 44px;
    font-size: 16px;
  }
}

/* ---------- Phone (under 768px): one column ---------- */

@media (max-width: 767px) {
  .wrap {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 24px;
  }

  /* Every grid child takes the full row. Written after the desktop spans so it wins. */
  .wrap > * {
    grid-column: 1 / -1;
    grid-row: auto;
  }

  /* Navbar: the logo floats on the left (fixed, inverted, as on desktop). "Book a call" and the menu button sit in a
     cream pill on the right, so they stay readable over images. The links live in a full-screen overlay. */
  .logo {
    top: 20px;
    left: var(--margin);
  }

  .nav {
    top: 0;
    left: auto;
    z-index: 20;
    height: var(--bar-h);
    padding: 0 8px 0 0;
    align-items: center;
  }

  .nav__pill {
    position: relative;
    z-index: 2;
    gap: 4px;
    padding: 4px;
  }

  /* The overlay lives inside the pill, so the two buttons are raised above it */
  .nav .btn {
    position: relative;
    z-index: 2;
    min-width: 0;
    padding: 0 16px;
  }

  .nav__links {
    display: none;
  }

  .js .nav__toggle {
    position: relative;
    z-index: 2;
    display: block;
    flex: none;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--ink);
    cursor: pointer;
  }

  .nav__toggle-bar {
    position: absolute;
    left: 12px;
    width: 20px;
    height: 2px;
    background: currentColor;
    transition: transform 200ms ease;
  }

  .nav__toggle-bar:first-child {
    top: 18px;
  }

  .nav__toggle-bar:last-child {
    top: 24px;
  }

  .nav__toggle[aria-expanded="true"] .nav__toggle-bar:first-child {
    transform: translateY(3px) rotate(45deg);
  }

  .nav__toggle[aria-expanded="true"] .nav__toggle-bar:last-child {
    transform: translateY(-3px) rotate(-45deg);
  }

  .nav__links.is-open {
    position: fixed;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: calc(var(--bar-h) + 24px) var(--margin) 32px;
    overflow-y: auto;
    background: var(--bg);
    pointer-events: auto;
  }

  .nav__links.is-open a {
    min-height: 56px;
    color: var(--ink);
    font-size: clamp(36px, 11vw, 56px);
    font-weight: 600;
    line-height: 1.1;
  }

  /* Hero: headline, then the visual full width. No pinning. */
  .hero {
    min-height: 0;
  }

  /* Work: collage images stacked, nothing sticky */
  .collage {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .collage__wide {
    grid-column: auto;
  }

  .collage__tall {
    grid-row: auto;
    aspect-ratio: 448 / 530;
  }

  .project .item-title {
    margin-bottom: 12px;
  }

  /* Services and Studio without JavaScript: image, name, text, tags */
  .pillar,
  .profile {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 16px;
  }

  .pillar > *,
  .profile > * {
    grid-column: 1 / -1;
    grid-row: auto;
  }

  /* Titles: pinned like on desktop, never taller than about a third of the screen (three lines at most 7.5svh each) */
  .section > .section-title,
  .section__head > .section-title {
    font-size: clamp(36px, min(17vw, 7.5svh), 72px);
  }

  .section__intro {
    max-width: none; /* the frame is full width on phones */
  }

  .pillar__body .tags,
  .project .tags,
  .profile__body .tags {
    margin-top: 16px;
  }

  /* Contact */
  .contact__intro .section-title {
    margin-bottom: 8px;
  }

  .form {
    height: auto;
    margin-top: 0;
  }

  .form__field--grow {
    flex: none;
  }

  .form__input--area {
    flex: none;
    min-height: 160px;
  }

  /* Footer */
  .site-footer {
    padding-bottom: 24px;
  }

  .footer__wink {
    margin-bottom: 0;
  }

  .footer__game {
    margin-left: 0;
  }

  /* Privacy Policy: the table turns into one block per row, labelled from data-label */
  .legal {
    padding-top: calc(var(--bar-h) + 48px);
  }

  .legal__updated {
    margin-bottom: 32px;
  }

  .legal__body h2 {
    margin-top: 40px;
  }

  .legal__body table,
  .legal__body tbody,
  .legal__body tr,
  .legal__body td {
    display: block;
  }

  .legal__body thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .legal__body tr {
    padding: 12px 0;
    border-bottom: 1px solid var(--neutral-200);
  }

  .legal__body td {
    padding: 4px 0;
    border: 0;
  }

  .legal__body td::before {
    display: block;
    color: var(--ink);
    font-weight: 600;
    content: attr(data-label);
  }
}

/* Narrow phones: "Programează un call" is the longest label, so the button gets a little smaller to clear the logo */
@media (max-width: 399px) {
  .nav .btn {
    padding: 0 12px;
    font-size: 14px;
  }
}

@media (max-width: 339px) {
  .nav .btn {
    padding: 0 10px;
    font-size: 13px;
  }
}

@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  .nav__links.is-open {
    animation: menu-in 200ms ease-out;
  }

  /* A gentle enter for the hero visual, since there is no zoom on phones */
  .hero__visual {
    animation: hero-enter 700ms ease-out both;
  }

  @keyframes menu-in {
    from {
      opacity: 0;
    }
  }

  @keyframes hero-enter {
    from {
      opacity: 0;
      transform: scale(0.96);
    }
  }
}

/* ---------- Scroll interactions ----------
   Sticky titles, the Work text and the stacks are CSS and work in every width. Everything driven by script is
   progressive enhancement and only applies with JavaScript on (.js):
   - hero zoom: from 768px up and when the visitor has not asked for reduced motion. Keep this media query identical
     to MOTION_QUERY in js/site.js.
   - hero growth on phones: under 768px and without reduced motion (PHONE_MOTION in js/site.js).
   - stacks (Services, Studio): the sticky frame and blocks are built by js/site.js; the image slide only runs without
     reduced motion. */

@media (min-width: 768px) {
  /* Work: the collage scrolls past, the project text stays in view next to it. A text taller than the space below
     --content-top pins higher (--pin, set by js/site.js), so its last tags stay on screen. */
  .project {
    align-self: start;
    position: sticky;
    top: var(--pin, var(--content-top));
  }
}

@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  /* Hero: the stage pins for one viewport of scroll while the visual grows (state 1 to state 2). */
  .js .hero {
    height: 200vh;
    height: 200svh;
    min-height: 0;
  }

  .js .hero__stage {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
  }

  .js .hero__slot {
    position: static;
  }

  .js .hero__visual {
    --cw: min(100vw, 1440px);
    --col: calc((var(--cw) - 2 * var(--margin) - 11 * var(--gutter)) / 12);
    --slot: calc(5 * var(--col) + 4 * var(--gutter));
    z-index: 1;
    border-radius: 0;
    /* First paint only: the state 1 box worked out from the grid. js/site.js measures it and takes over. */
    clip-path: inset(
      var(--hero-pad-top)
      calc((100vw - var(--cw)) / 2 + var(--margin))
      calc(100svh - var(--hero-pad-top) - var(--slot))
      calc((100vw - var(--cw)) / 2 + var(--margin) + 7 * (var(--col) + var(--gutter)))
      round 8px
    );
    will-change: clip-path;
  }
}

/* Phones: no pinning. The box below the headline grows with the scroll, taller and out to the screen edges (--g is 0 to 1, set by js/site.js). */
@media (max-width: 767px) and (prefers-reduced-motion: no-preference) {
  html {
    overflow-anchor: none; /* the page below moves while the box grows, the browser must not "correct" the scroll */
  }

  .js .hero__slot {
    --g: 0;
    --w: calc(100vw - 2 * var(--margin));
    aspect-ratio: auto;
    height: calc(var(--w) + var(--g) * (max(72svh, var(--w)) - var(--w)));
    margin-inline: calc(var(--margin) * var(--g) * -1);
  }

  .js .hero__visual {
    border-radius: calc(8px * (1 - var(--g)));
  }
}

/* ---------- Stacks: Services and Studio ----------
   site.js (initStacks) adds .is-stacked, moves the images into one sticky frame (.stack__sticky > .stack__media) and
   wraps the rest of each article (name and text) in .stack__text. Each block rises, pins level with the frame's top
   (--pin, set by site.js), holds for half a screen and moves on. The next image slides up into the frame while the
   current one shrinks to 80%, both clipped by the frame. The articles stay in the page as the real content. */

.stack {
  --stack-top: var(--content-top); /* where the frame pins */
  --stack-lead: calc(208 * var(--s)); /* how far below the frame's top a block starts rising (Figma) */
  --stack-hold: 50svh; /* how long a block stays pinned */
}

/* Services: the frame pins level with the section title and covers it (Figma 1171:2640) */
#services-stack {
  --stack-top: var(--title-top);
}

/* Services: only the image frame covers the sticky title. The body is see-through (the names and texts sit in
   columns the title does not reach). */
#services .section__body {
  background: transparent;
}

.is-stacked > .pillar,
.is-stacked > .profile {
  display: block;
  margin-top: 0;
  padding-top: var(--stack-lead);
}

/* The hold: a sticky block can only travel inside its article's content, so the hold is content, not padding */
.is-stacked > .pillar::after,
.is-stacked > .profile::after {
  display: block;
  height: var(--stack-hold);
  content: "";
}

.is-stacked .pillar__body,
.is-stacked .profile__body {
  margin-top: 0;
}

.stack__text {
  position: sticky;
  top: var(--pin, var(--stack-top));
}

.stack__sticky {
  position: sticky;
  top: var(--stack-top);
  z-index: 2;
}

.stack__media {
  display: grid; /* all images in one cell */
  overflow: hidden; /* the frame: images slide and shrink inside it, never outside */
  border-radius: var(--radius-s);
  background: var(--bg); /* the page colour around a shrinking image, not the grey placeholder (change round 5) */
}

.stack__media > * {
  grid-area: 1 / 1;
  transform: translateY(0); /* every image has a transform, so they paint in page order: the newer one on top */
}

.stack__media > .is-after {
  transform: translateY(100%); /* waiting below the frame */
}

.stack__media > .is-before {
  transform: scale(0.8); /* shrunk from the centre, under the image that slid in over it */
}

.stack.is-ready .stack__media > * {
  transition: transform 500ms cubic-bezier(0.33, 0, 0.67, 1); /* "easy ease" */
}

@media (prefers-reduced-motion: reduce) {
  .stack.is-ready .stack__media > * {
    transition: none;
  }
}

/* Desktop and wide tablets: the frame pins on the left (Services) or in the centre (Studio), the blocks pin beside it */
@media (min-width: 1024px) {
  .stack.is-stacked {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
    align-items: start;
  }

  .stack__sticky {
    grid-column: 1 / 6;
    grid-row: 1 / span var(--n, 1); /* site.js puts article i in row i + 1 */
  }

  #studio-stack .stack__sticky {
    grid-column: 6 / 9;
  }

  .is-stacked > .pillar,
  .is-stacked > .profile {
    grid-column: 1 / -1;
  }

  /* Same columns as the page grid: the names and texts keep their columns (.pillar__name, .profile__who, ...) */
  .stack__text {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--gutter);
    align-items: start;
  }

  .stack__media > .pillar__image,
  .stack__media > .profile__photo {
    width: 100%;
  }
}

/* Phones and small tablets: the frame pins as a solid block, the blocks pin just under it and then pass behind it */
@media (max-width: 1023px) {
  .stack.is-stacked {
    display: block;
  }

  .stack__sticky {
    padding-bottom: 16px;
    background: var(--bg);
  }

  /* Covers the strip between the navbar and the frame, so the blocks do not show up there after passing behind it.
     Only once the frame has pinned (.is-pinned, js/site.js): while it rises it must not cover the title early. */
  .stack.is-pinned .stack__sticky::before {
    position: absolute;
    right: 0;
    bottom: 100%;
    left: 0;
    height: var(--stack-top);
    background: var(--bg);
    content: "";
  }

  .stack__media {
    height: 40svh;
  }

  #studio-stack .stack__media {
    width: fit-content; /* the frame is as wide as the portrait */
  }

  .stack__media > * {
    height: 100%;
  }

  .stack__media > .pillar__image {
    aspect-ratio: auto;
    width: 100%;
  }

  .stack__media > .profile__photo {
    aspect-ratio: 332 / 457;
    width: auto;
  }

  .stack__text > * + * {
    margin-top: 12px;
  }
}
