@charset "UTF-8";

/* ==========================================================================
   MNas — Mohannad Nasser
   Built to the "M.nas one pager" comps. Brand Book 2026 (Layals).
   Primary #0B3532 · Secondary #D3C4A7
   Type: Noto Sans Display (Latin) · Noto Sans Hebrew · Noto Sans Arabic

   Layout: a fixed green panel and a scrolling content column. All directional
   properties are logical, so RTL (he, ar) and LTR (en) mirror from one source.
   ========================================================================== */

/* --------------------------------------------------------------- tokens -- */

:root {
  --ink: #0b3532;
  --sand: #d3c4a7;

  --ink-80: #3c5d5b;
  --ink-60: #6d8684;

  /* Figma uses two sands: a slightly warmer one for the page ground, and the
     brand book's #D3C4A7 for text and marks sitting on the green.
     Sampled from the Figma render of Desktop - 1. */
  --paper: #d5c3a2;
  --paper-soft: #dccfb9;

  /* Muted text colours. Previously these were achieved with opacity, which
     dropped several labels under the 4.5:1 AA threshold. These are solid
     values measured to pass against their own background. */
  --on-ink-muted: #a8a591;   /* on --ink  — 5.3:1 */
  --on-sand-muted: #2f4a45;  /* on --sand — 5.2:1 */

  --line-on-ink: rgba(211, 196, 167, 0.24);
  --line-on-ink-soft: rgba(211, 196, 167, 0.12);
  --line-on-sand: rgba(11, 53, 50, 0.22);
  --line-on-sand-soft: rgba(11, 53, 50, 0.1);

  --f-latin: "Noto Sans Display", ui-sans-serif, system-ui, sans-serif;
  --f: var(--f-latin);

  --t-name: clamp(2.4rem, 1rem + 4.4vw, 5rem);
  --t-role: clamp(0.95rem, 0.8rem + 0.7vw, 1.45rem);
  --t-h2: clamp(1.45rem, 1.1rem + 1.5vw, 2.35rem);
  --t-h3: clamp(1rem, 0.94rem + 0.3vw, 1.15rem);
  --t-lead: clamp(1.02rem, 0.94rem + 0.42vw, 1.3rem);
  --t-body: clamp(0.95rem, 0.9rem + 0.24vw, 1.06rem);
  --t-small: clamp(0.8rem, 0.77rem + 0.14vw, 0.875rem);
  --t-micro: 0.7rem;

  /* Figma Desktop-1: 429 / 1440 */
  --panel-w: 29.79%;
  --gutter: clamp(1.25rem, 0.6rem + 2.6vw, 3.75rem);

  --ease: cubic-bezier(0.22, 0.68, 0.32, 1);
}

.lang-he { --f: "Noto Sans Hebrew", var(--f-latin); }
/* Futura 100 Arabic (Adobe Fonts) is the brand face; Noto Sans Arabic is the
   fallback for hosts the Typekit kit is not registered for. */
.lang-ar { --f: "futura-100-arabic", "Noto Sans Arabic", var(--f-latin); }

/* ---------------------------------------------------------------- reset -- */

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

html {
  -webkit-text-size-adjust: 100%;
  height: 100%;
  overscroll-behavior: none;
}

body {
  margin: 0;
  height: 100%;
  /* Nothing outside .scroller scrolls, so any pull at the top or bottom is the
     browser's own rubber-band — which drags the whole fixed layout with it and
     can trigger pull-to-refresh. Refuse it here and keep it contained inside
     the one element that does scroll. */
  overscroll-behavior: none;
  background: var(--ink);
  color: var(--ink);
  font-family: var(--f);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

/* Year ranges and Latin strings inside RTL text. */
.ltr { unicode-bidi: isolate; }

:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 2px; }
/* The section heading is focused by script on every section change so that a
   screen reader announces it. That is not a keyboard interaction, so it should
   not draw a focus ring — site.js records what the visitor last used. */
html[data-nav="pointer"] .sec__title:focus,
html[data-nav="pointer"] .sec__title:focus-visible { outline: none; }
.panel :focus-visible, .menu :focus-visible, .foot :focus-visible { outline-color: var(--sand); }

::selection { background: var(--ink); color: var(--sand); }

.skip {
  position: fixed;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  z-index: 300;
  padding: 0.7rem 1.1rem;
  background: var(--ink);
  color: var(--sand);
  font-size: var(--t-small);
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease);
}
.skip:focus { transform: none; }

/* ---------------------------------------------------------------- shell -- */
/* Desktop: two columns filling the viewport. Only .scroller scrolls. */

.shell {
  display: grid;
  /* .panel is first in source order, so it takes the first track. In RTL that
     lands it on the right, in LTR on the left — the mirror comes for free. */
  grid-template-columns: var(--panel-w) minmax(0, 1fr);
  height: 100dvh;
  overflow: hidden;
}

/* ============================ GREEN PANEL ============================== */

.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--ink);
  color: var(--sand);
  overflow: hidden;
  padding: clamp(1.25rem, 2vw, 2.25rem);
}

/* The watermark. Static — it never scrolls with the content. */
.panel__bg {
  position: absolute;
  inset: 0;
  background-image: url("background.svg");
  background-repeat: repeat-y;
  background-position: center top;
  background-size: 100% auto;
  opacity: 0.85;
  pointer-events: none;
}

.panel__top,
.panel__section,
.panel__foot { position: relative; }

.panel__top {
  flex: 0 0 auto;
  display: flex;
  justify-content: center;
  padding-block-start: clamp(1.5rem, 4vh, 4rem);
  margin-block-end: clamp(1rem, 2vw, 1.75rem);
}

.panel__portrait {
  width: min(78%, 17.5rem);
  height: auto;
  /* The cut-out sits on a hairline, as in the comp. */
  border-block-end: 1px solid var(--line-on-ink);
}

.panel__section {
  flex: 0 0 auto;
  text-align: center;
  font-size: var(--t-h3);
  font-weight: 600;
  line-height: 1.3;
  /* Auto margins do the centring, so the label sits in the middle of whatever
     gap is left instead of forcing a fixed block of height into a column that
     has none to spare — a tall line-height here pushed the languages line and
     the tagline off the bottom of the panel on a short window. */
  margin-block: auto;
  padding-block: 1.5rem;
  transition: opacity 0.3s var(--ease);
}

.panel__foot {
  flex: 0 0 auto;
  display: grid;
  justify-items: center;
  gap: clamp(0.85rem, 1.6vw, 1.4rem);
  text-align: center;
}

.qr img { width: clamp(72px, 7vw, 108px); height: auto; }

.panel__langs {
  display: grid;
  gap: 0.2rem;
  font-size: var(--t-micro);
  line-height: 1.5;
  color: var(--on-ink-muted);
  max-width: 22rem;
}
.panel__langs-label {
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--on-ink-muted);
}
.lang-he .panel__langs-label,
.lang-ar .panel__langs-label { letter-spacing: 0; text-transform: none; }

.panel__tagline { width: clamp(150px, 15vw, 206px); height: auto; }

/* ------------------------------------------------------------- contact -- */

/* The comp stacks each contact centred: icon, then label, then value. */
.contact { display: grid; gap: 0.5rem; width: 100%; max-width: 18rem; }

.contact__row {
  display: grid;
  justify-items: center;
  gap: 0.08rem;
  padding: 0.1rem;
  transition: opacity 0.25s var(--ease);
  text-align: center;
}
.contact__row:hover { opacity: 0.75; }

.ico { width: 0.82rem; height: 0.82rem; opacity: 0.8; }

.contact__body { display: grid; gap: 0; min-width: 0; justify-items: center; }

.contact__label {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-ink-muted);
  line-height: 1.5;
}
.lang-he .contact__label,
.lang-ar .contact__label { letter-spacing: 0; text-transform: none; font-size: 0.66rem; }

.contact__value {
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

/* =========================== CONTENT COLUMN ============================ */

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--paper);
  overflow: hidden;
}

/* ------------------------------------------------------------ masthead -- */
/* Fixed: logo, nav, name and role stay put while sections scroll past. */

.masthead {
  flex: 0 0 auto;
  padding: clamp(1rem, 1.8vw, 1.9rem) var(--gutter) 0;
}

.masthead__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem clamp(1rem, 2.5vw, 2.5rem);
  min-height: 3rem;
}

/* The comp sits the logo at the inline-end of the bar (left in Hebrew and
   Arabic, right in English), with the language switcher opposite it. */
.brand { flex: 0 0 auto; order: 2; margin-inline-start: auto; color: var(--ink); }
.brand svg { width: clamp(58px, 5vw, 76px); height: auto; }

/* order:3 pushes the nav onto its own line beneath the logo row. */
.nav { flex: 1 0 100%; order: 3; min-width: 0; }
.nav__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 0.4rem clamp(0.85rem, 1.8vw, 1.75rem);
}
.nav a {
  position: relative;
  display: inline-block;
  padding-block: 0.3rem;
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--on-sand-muted);
  white-space: nowrap;
  transition: color 0.25s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: var(--origin, left) center;
  transition: transform 0.35s var(--ease);
}
[dir="rtl"] .nav a::after { --origin: right; }
.nav a:hover { color: var(--ink); }
.nav a.is-active { color: var(--ink); font-weight: 600; }
.nav a:hover::after,
.nav a.is-active::after { transform: scaleX(1); }

.masthead__end {
  flex: 0 0 auto;
  order: 1;
  display: flex;
  align-items: center;
  flex-direction: row-reverse;
  gap: 0.75rem;
}

/* The switcher is a fixed chip stack sitting directly above the accessibility
   button, sharing its corner and its ink-on-sand treatment so the two read as
   one cluster. It carries its own background rather than inheriting the page's,
   so it stays legible wherever it happens to sit. */
.langs {
  position: fixed;
  z-index: 250;
  inset-block-end: calc(var(--fab-bottom) + var(--fab-size) + 0.55rem);
  inset-inline-end: var(--fab-inset);
  font-family: var(--f);
}
/* Collapsed to the current language; the list is the menu it opens. Without
   JS the toggle is hidden and the list stands on its own as three links. */
.langs__toggle {
  display: grid;
  place-items: center;
  width: var(--fab-size);
  height: var(--fab-size);
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: var(--ink);
  color: var(--sand);
  border: 1px solid var(--sand);
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 2px 10px rgba(11, 53, 50, 0.35);
  transition: transform 0.25s var(--ease);
}
.langs__toggle:hover { transform: scale(1.06); }
html.no-js .langs__toggle { display: none; }

.langs__list {
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  width: var(--fab-size);
  padding: 0.35rem 0;
  background: var(--ink);
  border: 1px solid var(--sand);
  border-radius: calc(var(--fab-size) / 2);
  box-shadow: 0 2px 10px rgba(11, 53, 50, 0.35);
}
/* Opens upward, out of the toggle — the FAB is below it. */
html:not(.no-js) .langs__list {
  position: absolute;
  inset-block-end: calc(100% + 0.45rem);
  inset-inline-end: 0;
  opacity: 0;
  transform: translateY(0.4rem);
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
html:not(.no-js) .langs__list.is-open { opacity: 1; transform: none; }
.langs__list[hidden] { display: none; }
.langs__link {
  display: grid;
  place-items: center;
  /* Square-ish chips: 34x34 keeps the pill compact while staying a comfortable
     touch target (and well clear of the 24x24 minimum). */
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1;
  color: var(--on-ink-muted);
  transition: color 0.25s var(--ease), background 0.25s var(--ease);
}
.langs__link:hover { color: var(--sand); }
.langs__link.is-current {
  background: var(--sand);
  color: var(--ink);
  font-weight: 700;
}
.langs :focus-visible { outline-color: var(--sand); }

/* Name and role */

.masthead__id { padding-block: clamp(0.35rem, 1.1vw, 1.1rem) 0; }

.name {
  font-size: var(--t-name);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  /* Percentage padding resolves against the CONTAINING BLOCK'S WIDTH, not its
     height — so this is 1% of .masthead__id's width, and it grows as the
     viewport widens. */
  padding-block-end: 1%;
}
.lang-he .name { letter-spacing: 0; line-height: 1.05; }
.lang-ar .name { letter-spacing: 0; line-height: 1.3; }

/* The reversed bar under the name, as in the comp. */
.role {
  display: inline-block;
  margin-block-start: clamp(0.5rem, 1vw, 0.9rem);
  padding: 0.42em 0.85em;
  background: var(--ink);
  color: var(--sand);
  font-size: var(--t-role);
  font-weight: 700;
  line-height: 1.32;
}

/* ------------------------------------------------------------ scroller -- */

.scroller {
  overscroll-behavior: contain;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  /* Nothing scrolls: sections are shrunk to fit and cross-faded. The class
     is set by script only for a section that could not be fitted at the
     legibility floor — clipping it would put content out of reach. */
  overflow: hidden;
  overscroll-behavior: contain;
  /* No smooth scrolling: sections cross-fade rather than scroll, and the
     only programmatic scroll left is the reset to top during a swap, which
     must be instant so it happens while the panel is faded out. */
  padding: clamp(1.5rem, 3vw, 2.75rem) var(--gutter) 0;
  scrollbar-width: thin;
  scrollbar-color: rgba(11, 53, 50, 0.3) transparent;
}
.scroller:focus { outline: none; }

.scroller::-webkit-scrollbar { width: 8px; }
.scroller::-webkit-scrollbar-thumb {
  background: rgba(11, 53, 50, 0.28);
  border-radius: 4px;
}
.scroller::-webkit-scrollbar-track { background: transparent; }

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

/* -------------------------------------------------------------- section -- */

.sec {
  padding-block-end: clamp(2.75rem, 6vw, 5rem);
  scroll-margin-block-start: 0;
}
.sec + .sec { border-block-start: 1px solid var(--line-on-sand-soft); padding-block-start: clamp(2.25rem, 5vw, 4rem); }

/* The green panel names the section, so the heading is not repeated above
   the copy — but it stays in the document for screen readers, for the
   heading outline, and as the focus target when a nav item is clicked. */
.sec__head {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.sec__title { font-size: var(--t-h2); }

.sec__body { display: grid; gap: 0.8rem; max-width: 62ch; }
.sec__body p { line-height: 1.58; }

.lead { font-size: var(--t-lead); font-weight: 600; line-height: 1.45; }

/* -------------------------------------------------------------- awards -- */

.awards { display: grid; gap: 1.25rem; margin-block-start: 0.3rem; }

.award__link { display: grid; gap: 0.2rem; width: -moz-fit-content; width: fit-content; }

.award__src {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: var(--f-latin);
  font-size: var(--t-h3);
  font-weight: 700;
  position: relative;
}
.award__src::after {
  content: "";
  position: absolute;
  inset-block-end: -2px;
  inset-inline-start: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
  transform: scaleX(0);
  transform-origin: var(--origin, left) center;
  transition: transform 0.35s var(--ease);
}
[dir="rtl"] .award__src::after { --origin: right; }
.award__link:hover .award__src::after,
.award__link:focus-visible .award__src::after { transform: scaleX(1); }

.award__line {
  font-family: var(--f-latin);
  font-size: var(--t-small);
  font-weight: 500;
  line-height: 1.6;
  color: var(--on-sand-muted);
}

.ext { width: 0.6em; height: 0.6em; flex: 0 0 auto; opacity: 0.55; }
a:hover .ext { opacity: 1; }

/* --------------------------------------------------------------- areas -- */

.areas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(1.1rem, 2.2vw, 1.9rem);
  max-width: none;
}
.sec__body:has(.areas) { max-width: none; }

.area { padding-block-start: 0.85rem; border-block-start: 1px solid var(--line-on-sand); }
.area__title { font-size: var(--t-h3); font-weight: 700; line-height: 1.35; margin-block-end: 0.35rem; }
.area__text { font-size: var(--t-small); line-height: 1.6; color: var(--on-sand-muted); }

/* --------------------------------------------------------------- roles -- */

/* Named .job, not .role — .role is the reversed bar under the name, and the
   two collided. */
.roles { display: grid; gap: clamp(1.5rem, 3vw, 2.4rem); max-width: 68ch; }

.job__years {
  font-family: var(--f-latin);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--on-sand-muted);
  margin-block-end: 0.15rem;
}

.job__title { font-size: var(--t-h3); font-weight: 700; line-height: 1.4; }
.job__org { font-weight: 500; color: var(--on-sand-muted); }
.job__text { font-size: var(--t-small); line-height: 1.6; color: var(--on-sand-muted); margin-block-start: 0.35rem; }

/* ------------------------------------------------------------- degrees -- */

.degrees { display: grid; gap: clamp(0.9rem, 1.8vw, 1.4rem); max-width: 60ch; }
.degree__title { font-size: var(--t-h3); font-weight: 700; line-height: 1.4; }
.degree__year { font-weight: 500; color: var(--on-sand-muted); }
.degree__text { font-size: var(--t-small); line-height: 1.55; color: var(--on-sand-muted); margin-block-start: 0.1rem; }

/* The bar-membership line reads as one of the entries, not as a footnote —
   same size and weight as a qualification title, and no rule above it. */
.degrees__note {
  margin-block-start: clamp(1rem, 2vw, 1.5rem);
  font-size: var(--t-h3);
  font-weight: 700;
  line-height: 1.4;
}

/* --------------------------------------------------------------- legal -- */

.legal {
  display: grid;
  gap: 0.25rem;
  padding-block: clamp(1.25rem, 3vw, 2rem) clamp(2rem, 5vw, 3.5rem);
  border-block-start: 1px solid var(--line-on-sand-soft);
  font-size: 0.78rem;
  color: var(--on-sand-muted);
  max-width: 48ch;
}

/* ---------------------------------------------------------------- foot -- */
/* Narrow screens only — the desktop panel already carries the contact. */

.foot { display: none; }

/* ============================ MOBILE MENU ============================== */

/* No frame around it — just the glyph. The button keeps its box size so the
   tap target stays comfortably large, and focus still shows an outline. */
.burger {
  display: none;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  color: var(--ink);
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  cursor: pointer;
  transition: opacity 0.3s var(--ease);
}
.burger:hover { opacity: 0.7; }
.burger__box { display: grid; gap: 6px; place-content: center; width: 100%; height: 100%; }
.burger__box span {
  display: block;
  width: 18px;
  height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease);
}
.burger[aria-expanded="true"] .burger__box span:first-child { transform: translateY(3.5px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__box span:last-child { transform: translateY(-3.5px) rotate(-45deg); }

.menu {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  background: var(--ink);
  color: var(--sand);
  opacity: 0;
  transition: opacity 0.35s var(--ease);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 5.5rem var(--gutter) 3rem;
}
.menu[hidden] { display: none; }
.menu.is-open { opacity: 1; }
.menu__inner { width: 100%; }

.menu__close {
  position: fixed;
  z-index: 2;
  inset-block-start: clamp(0.9rem, 3.5vw, 1.5rem);
  inset-inline-start: var(--gutter);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  color: var(--sand);
  cursor: pointer;
  transition: opacity 0.3s var(--ease);
}
.menu__close:hover { opacity: 0.7; }
.menu__close:focus-visible { outline-color: var(--sand); }
.menu__close svg { width: 1.3rem; height: 1.3rem; }

.menu__list { display: grid; gap: clamp(0.3rem, 1.4vw, 0.8rem); }
.menu__list a {
  display: block;
  padding-block: 0.4rem;
  font-size: clamp(1.35rem, 1rem + 2.6vw, 2.2rem);
  font-weight: 500;
  line-height: 1.25;
  opacity: 0;
  transform: translateY(0.8rem);
  transition:
    opacity 0.45s var(--ease) calc(var(--d, 0) * 50ms + 80ms),
    transform 0.45s var(--ease) calc(var(--d, 0) * 50ms + 80ms);
}
.menu.is-open .menu__list a { opacity: 1; transform: none; }
.menu__foot {
  display: grid;
  gap: 0.35rem;
  margin-block-start: clamp(2rem, 5vw, 3rem);
  padding-block-start: 1.25rem;
  border-block-start: 1px solid var(--line-on-ink);
  opacity: 0;
  transform: translateY(0.8rem);
  transition:
    opacity 0.45s var(--ease) calc(var(--d, 0) * 50ms + 80ms),
    transform 0.45s var(--ease) calc(var(--d, 0) * 50ms + 80ms);
}
.menu.is-open .menu__foot { opacity: 1; transform: none; }
.menu__contact {
  font-size: var(--t-body);
  opacity: 0.8;
  width: -moz-fit-content;
  width: fit-content;
  overflow-wrap: anywhere;
}
.menu__contact:hover { opacity: 1; }

html.menu-open, html.menu-open body { overflow: hidden; }

/* ========================================================================
   NARROW SCREENS
   The green hero is pinned at the top; the sand content scrolls beneath it.
   ======================================================================== */

@media (max-width: 61.9375rem) {
  /* Pinned hero, scrolling content, pinned contact bar. */
  .shell {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  /* Geometry measured off the comp, as a share of viewport width:
       portrait  top 7.1%   width 27%   (its 840x799 aspect makes that 25.7vw
                                         tall, landing the hero bottom at 32.8%)
       name      top 17.9%  bottom 23.0%
       role bar  top 25.1%  bottom 28.7%   right edge 71.4%
     The portrait bleeds to the edge, so the panel carries no inline padding. */
  /* ------------------------------------------------------------------
     Hero geometry is taken straight off the comp, measured as a share of
     viewport width and expressed in vw so it holds at every phone size:

       hero bottom   32.8      portrait  left 72.9  width 27   top 7.1
       name ink      right edge 67.0     top 17.9   cap 5.1
       role bar      left 13.7  right 71.4          top 25.1  bottom 28.7

     The bar therefore runs PAST the name on the reading-start side and stops
     just short of the portrait; the portrait paints above it.
     The gutter is subtracted where a value is measured from the viewport
     edge but applied inside the masthead's padded box.
     ------------------------------------------------------------------ */
  .panel {
    flex-direction: row;
    align-items: flex-end;
    gap: 0;
    /* Gutter, not 5%: the portrait's outer corner then lines up exactly with
       the edge of the text below it. */
    padding: 7.1vw var(--gutter) 0;
    min-height: 36vw;
  }

  .panel__top {
    order: 2;
    margin: 0;
    padding: 0;
    align-self: flex-end;
    flex: 0 0 auto;
    width: 27vw;
    max-width: none;
  }
  /* Fills its box, so the box width IS the portrait width and the corner lands
     on the gutter. 27vw is the ceiling: past it the portrait starts covering
     the end of the name (which begins at 67vw) and the start of the role
     sentence. */
  .panel__portrait { border: 0; width: 100%; }

  .panel__section,
  .panel__foot { display: none; }

  .main { background: var(--paper); min-height: 0; }

  .masthead {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    z-index: 5;
    /* No block padding here: it is the containing block for the absolutely
       positioned name/bar, and a px-clamped padding shifted their vw offsets
       by a different amount at every viewport size. The logo row carries its
       own spacing instead. */
    padding: 0 var(--gutter);
    pointer-events: none;
  }
  .masthead > * { pointer-events: auto; }
  .masthead__bar { min-height: 0; padding-block-start: 2vw; }

  .brand { color: var(--sand); }
  .brand svg { width: clamp(42px, 11vw, 60px); }
  .nav { display: none; }
  .burger {
    display: block;
    color: var(--sand);
    width: 2.4rem;
    height: 2.4rem;
  }
  /* It sits on the green band here, so the page's ink focus ring would be
     invisible against it. */
  .burger:focus-visible { outline-color: var(--sand); }

  /* Pinned in vw rather than stacked under the logo row, whose height comes
     from px clamps — that made the name and bar drift vertically as the
     viewport changed. 16.5vw puts the name's ink top at the comp's 17.9. */
  .masthead__id {
    position: absolute;
    inset-inline: var(--gutter);
    inset-block-start: 16.5vw;
    width: auto;
    /* Clear the desktop rule's padding, which pushed the name down. */
    padding-block: 0;
  }

  /* Futura 100 Arabic has a shorter ink box than Noto Sans Arabic, so Arabic
     no longer needs to drop as far below the shared 7.1vw to clear the gap
     between the logo row and the bar. Swept against the bar's top edge at 390,
     360 and 320: this is the largest setting that still clears at all three. */
  .lang-ar .name { font-size: 6.3vw; margin-block-start: -1.8vw; }

  /* Name's reading-start edge lands at 67vw. */
  .name {
    display: block;
    width: calc(67vw - var(--gutter));
    margin-inline-start: auto;
    font-size: 7.1vw;
    line-height: 1.12;
    color: var(--sand);
  }

  /* Box spans 13.7vw..71.4vw. The 4.4vw inline-start padding puts the first
     word of the role directly under the first word of the name, while the
     box itself carries on past it toward the portrait. */
  .role {
    /* Pinned rather than stacked under the name: Hebrew, Arabic and Latin
       line boxes differ in height, which put the bar at three different
       heights. 16.5 + 8.6 = the comp's 25.1vw, in every language. */
    position: absolute;
    inset-block-start: 8.6vw;
    inset-inline-start: calc(22.6vw - var(--gutter));
    /* The desktop rule's margin still applied and shifted the pinned bar. */
    margin: 0;
    width: 68.7vw;
    padding-inline-start: 11.4vw;
    padding-inline-end: 0.7em;
    padding-block: 0.28em;
    background: var(--sand);
    color: var(--ink);
    /* At 2vw the sentence filled its bar to the pixel in every language — the
       English one exactly, with nothing to spare — so the only way to set it
       larger is to let it take a second line and give the band the room. */
    font-size: clamp(0.5rem, 2.8vw, 1.05rem);
    line-height: 1.25;
    overflow: hidden;
  }

  /* Portrait paints over the bar, not under it. */
  .panel__top { position: relative; z-index: 6; }

  .scroller { padding-block-start: clamp(1.5rem, 4vw, 2.25rem); }

  /* On mobile the green panel is gone, so nothing else names the section —
     the headings come back visually. */
  .sec__head {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 clamp(0.6rem, 2.2vw, 1rem);
    padding: 0;
    overflow: visible;
    clip-path: none;
    white-space: normal;
  }
  .sec__title {
    font-size: clamp(1.15rem, 5vw, 1.6rem);
    font-weight: 700;
    line-height: 1.25;
  }
  .lang-ar .sec__title { line-height: 1.45; }

  /* The static contact bar — outside .scroller, so it stays put while the
     content scrolls past above it.
     The comp reads tagline → e-mail → phone → QR from left to right. That is
     the visual order in every language, so in RTL the row is reversed rather
     than mirrored. */
  .foot {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: space-between;
    gap: clamp(0.5rem, 2.4vw, 1.1rem);
    padding: 0.5rem var(--gutter);
    /* Same MN watermark as the hero band, oversized and cropped so the
       letterforms read at the same scale rather than shrinking to fit.
       Centred vertically, the crop landed on the seam between two rows of the
       artwork, which read as a stray line through the monogram — 12% puts the
       window inside one row. */
    background: var(--ink) url("background 2.svg") repeat-x center 12% / auto 320%;
    color: var(--sand);
  }
  [dir="rtl"] .foot { flex-direction: row-reverse; }

  /* Keep the bar's contents clear of the pattern. */
  .foot > * { position: relative; }

  .foot__tagline { width: clamp(62px, 17vw, 140px); height: auto; flex: 0 0 auto; }

  .foot .contact {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: clamp(0.55rem, 3vw, 1.4rem);
    width: auto;
    max-width: none;
    min-width: 0;
  }
  .foot .contact li { min-width: 0; }
  .foot .contact__label { display: none; }

  /* Keep the same visual order in every language: e-mail then phone,
     reading inward from the tagline. */
  [dir="ltr"] .foot .contact { flex-direction: row-reverse; }

  .foot .contact__row {
    grid-auto-flow: column;
    align-items: center;
    gap: 0.45em;
    padding: 0;
  }
  .foot .contact__value {
    font-size: clamp(0.58rem, 2.35vw, 0.74rem);
    white-space: nowrap;
  }
  .foot .ico { width: 0.95em; height: 0.95em; opacity: 0.75; }

  /* The QR beside it already opens WhatsApp — don't say it twice. */
  .foot .contact__wa { display: none; }

  .qr--foot { flex: 0 0 auto; }
  .qr--foot img { width: clamp(26px, 7vw, 42px); height: auto; }

}



/* -------------------------------------------------------------- print -- */

@media print {
  .panel__bg, .burger, .menu, .skip, .langs { display: none !important; }
  html, body, .shell, .main, .scroller { height: auto; overflow: visible; }
  .shell { display: block; }
  body { background: #fff; color: #000; }
  .panel { background: #fff; color: #000; }
  .role { background: none; color: #000; padding: 0; }
}

/* ==========================================================================
   Accessibility widget
   An addition for visitors who want adjustments — NOT a substitute for the
   page conforming to IS 5568 / WCAG 2.0 AA on its own.
   ========================================================================== */

/* The anchor for BOTH the accessibility button and the language switcher above
   it, so moving one moves the other. The horizontal and vertical insets are
   separate: mobile lifts the pair over the fixed contact bar, and that lift
   must not also shove them sideways. */
:root {
  --fab-inset: clamp(1rem, 3vw, 1.75rem);   /* from the inline edge */
  --fab-bottom: clamp(1rem, 3vw, 1.75rem);  /* from the bottom */
  --fab-size: 3rem;
}

.a11y {
  position: fixed;
  z-index: 250;
  inset-block-end: var(--fab-bottom);
  /* Inline-END: the left in Hebrew and Arabic, the right in English. */
  inset-inline-end: var(--fab-inset);
  font-family: var(--f);
}

/* The floating button. 48px square — comfortably over the 44px target size
   guidance, and it never sits under the fixed contact bar on mobile. */
.a11y__fab {
  display: grid;
  place-items: center;
  width: var(--fab-size);
  height: var(--fab-size);
  padding: 0;
  border: 1px solid var(--sand);
  border-radius: 50%;
  background: var(--ink);
  color: var(--sand);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(11, 53, 50, 0.35);
  transition: transform 0.25s var(--ease), background 0.25s var(--ease);
}
.a11y__fab:hover { transform: scale(1.06); }
.a11y__fab svg { width: 1.35rem; height: 1.35rem; }

.a11y__panel {
  position: absolute;
  inset-block-end: calc(100% + 0.65rem);
  /* Hangs from the same edge as the button, so it never runs off-screen. */
  inset-inline-end: 0;
  width: min(17.5rem, calc(100vw - 2rem));
  max-height: min(30rem, calc(100vh - 6rem));
  overflow-y: auto;
  padding: 0.9rem;
  background: var(--ink);
  color: var(--sand);
  border: 1px solid var(--sand);
  box-shadow: 0 6px 26px rgba(11, 53, 50, 0.4);
  opacity: 0;
  transform: translateY(0.4rem);
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease);
}
.a11y__panel[hidden] { display: none; }
.a11y__panel.is-open { opacity: 1; transform: none; }

.a11y__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-block-end: 0.75rem;
}
.a11y__title { font-size: 0.9rem; font-weight: 700; }
.a11y__close {
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  border: 1px solid var(--line-on-ink);
  background: none;
  color: var(--sand);
  cursor: pointer;
}
.a11y__close svg { width: 0.7rem; height: 0.7rem; }
.a11y__close:hover { border-color: var(--sand); }

.a11y__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.5rem;
  margin-block-end: 0.75rem;
}
.a11y__step {
  min-height: 2.5rem;
  padding: 0.35rem;
  border: 1px solid var(--line-on-ink);
  background: none;
  color: var(--sand);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.a11y__step span { font-size: 0.8em; }
.a11y__step:hover { border-color: var(--sand); }
.a11y__scale { font-size: 0.8rem; font-weight: 700; min-width: 3.2rem; text-align: center; }

.a11y__list { display: grid; gap: 0.3rem; }

.a11y__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  width: 100%;
  min-height: 2.5rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--line-on-ink);
  background: none;
  color: var(--sand);
  font: inherit;
  font-size: 0.82rem;
  text-align: start;
  cursor: pointer;
}
.a11y__toggle:hover { border-color: var(--sand); }

.a11y__switch {
  flex: 0 0 auto;
  width: 2rem;
  height: 1.1rem;
  border: 1px solid var(--sand);
  border-radius: 1rem;
  position: relative;
  transition: background 0.2s var(--ease);
}
.a11y__switch::after {
  content: "";
  position: absolute;
  inset-block-start: 1px;
  inset-inline-start: 1px;
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 50%;
  background: var(--sand);
  transition: transform 0.2s var(--ease);
}
.a11y__toggle[aria-pressed="true"] .a11y__switch { background: var(--sand); }
.a11y__toggle[aria-pressed="true"] .a11y__switch::after {
  background: var(--ink);
  transform: translateX(0.9rem);
}
[dir="rtl"] .a11y__toggle[aria-pressed="true"] .a11y__switch::after { transform: translateX(-0.9rem); }

.a11y__reset,
.a11y__statement {
  display: block;
  width: 100%;
  margin-block-start: 0.55rem;
  padding: 0.5rem;
  min-height: 2.5rem;
  border: 1px solid var(--sand);
  background: var(--sand);
  color: var(--ink);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}
.a11y__statement {
  background: none;
  color: var(--sand);
  border-color: var(--line-on-ink);
  text-decoration: underline;
}
.a11y__statement:hover { border-color: var(--sand); }

/* Keep the button clear of the fixed contact bar on narrow screens. */
@media (max-width: 61.9375rem) {
  /* Clear the fixed contact bar — vertically only. */
  :root { --fab-bottom: calc(3.5rem + clamp(0.75rem, 3vw, 1.25rem)); }
}

@media print { .a11y { display: none; } }

/* --------------------------------------------------------------------------
   The adjustments themselves. Scoped to <html> classes so nothing here runs
   until a visitor asks for it.
   -------------------------------------------------------------------------- */

/* Text size. Applied to the root font-size so rem-based type scales; the
   hero's vw-based type is nudged along with a companion multiplier. */
html.a11y-scaled { font-size: calc(100% * var(--a11y-scale, 1)); }
html.a11y-scaled .name { font-size: calc(7.1vw * var(--a11y-scale, 1)); }
html.a11y-scaled .role { font-size: calc(clamp(0.53rem, 2.32vw, 0.92rem) * var(--a11y-scale, 1)); }

/* High contrast: pure black/white, keeping the brand structure intact. */
html.a11y-contrast {
  --ink: #000000;
  --sand: #ffffff;
  --paper: #ffffff;
  --on-ink-muted: #ffffff;
  --on-sand-muted: #000000;
  --line-on-ink: rgba(255, 255, 255, 0.6);
  --line-on-sand: rgba(0, 0, 0, 0.6);
  --line-on-sand-soft: rgba(0, 0, 0, 0.4);
  --line-on-ink-soft: rgba(255, 255, 255, 0.4);
}
html.a11y-contrast .panel__bg,
html.a11y-contrast .foot { background-image: none; }
html.a11y-contrast .role { border: 1px solid currentColor; }

html.a11y-invert { filter: invert(1) hue-rotate(180deg); }
html.a11y-invert img,
html.a11y-invert .a11y__fab { filter: invert(1) hue-rotate(180deg); }

html.a11y-grayscale { filter: grayscale(1); }
html.a11y-invert.a11y-grayscale { filter: invert(1) grayscale(1); }

/* Links get an unmistakable treatment, not just colour. */
html.a11y-links a:not(.a11y__statement) {
  text-decoration: underline !important;
  text-underline-offset: 2px;
  outline: 1px dashed currentColor;
  outline-offset: 2px;
}

html.a11y-readable,
html.a11y-readable body,
html.a11y-readable .name,
html.a11y-readable .role,
html.a11y-readable .sec__title {
  font-family: Arial, "Noto Sans Hebrew", "Noto Sans Arabic", sans-serif !important;
  letter-spacing: normal !important;
}

html.a11y-cursor,
html.a11y-cursor * {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M6 2l22 16-10 2 6 12-5 3-6-12-7 7z' fill='%23fff' stroke='%23000' stroke-width='2.2' stroke-linejoin='round'/%3E%3C/svg%3E") 4 2, auto !important;
}

html.a11y-motion *,
html.a11y-motion *::before,
html.a11y-motion *::after {
  animation: none !important;
  transition: none !important;
  scroll-behavior: auto !important;
}

/* ==========================================================================
   Document pages (accessibility statement)
   ========================================================================== */

.doc-body { background: var(--paper); color: var(--ink); }

.doc {
  max-width: 44rem;
  margin-inline: auto;
  padding: clamp(2rem, 6vw, 4.5rem) var(--gutter) clamp(3rem, 8vw, 6rem);
}

.doc__back {
  display: inline-block;
  margin-block-end: clamp(1.5rem, 4vw, 2.5rem);
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--on-sand-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.doc__back:hover { color: var(--ink); }

.doc__title {
  font-size: clamp(1.8rem, 1.2rem + 2.4vw, 2.75rem);
  font-weight: 700;
  line-height: 1.15;
  margin-block-end: clamp(1rem, 2.5vw, 1.6rem);
}

.doc__lede { font-size: var(--t-lead); line-height: 1.55; font-weight: 500; }

.doc h2 {
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
  font-weight: 700;
  margin-block: clamp(1.75rem, 4vw, 2.5rem) 0.6rem;
  padding-block-start: clamp(1.25rem, 3vw, 1.75rem);
  border-block-start: 1px solid var(--line-on-sand);
}

.doc p { line-height: 1.65; margin-block-end: 0.75rem; }

.doc__list { display: grid; gap: 0.5rem; margin-block-end: 0.75rem; }
.doc__list li {
  position: relative;
  padding-inline-start: 1.1rem;
  line-height: 1.6;
}
.doc__list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.72em;
  width: 0.5rem;
  height: 1px;
  background: currentColor;
}
.doc a { text-decoration: underline; text-underline-offset: 3px; }

/* Marks the fields that still need real details before publication. */
.doc__todo {
  padding: 0.75rem 1rem;
  border: 1px dashed var(--line-on-sand);
  background: rgba(11, 53, 50, 0.04);
  font-weight: 600;
}

.doc__meta {
  margin-block-start: clamp(2rem, 5vw, 3rem);
  font-size: var(--t-small);
  color: var(--on-sand-muted);
}

/* ==========================================================================
   Panel view — one section at a time, cross-faded
   Applied only when script is running (.js-panels). Without it every section
   stays stacked and readable, and the nav items stay ordinary anchors.
   ========================================================================== */

/* Native [hidden] must win over any display set on .sec. */
.sec[hidden] { display: none !important; }

.scroller { transition: opacity 180ms var(--ease); }
.scroller.is-fading { opacity: 0; }
.scroller.is-overflowing { overflow-y: auto; }

/* Only one section shows, so the separator between consecutive sections
   would otherwise sit above whichever one is on screen. */
.js-panels .sec + .sec {
  border-block-start: 0;
  padding-block-start: 0;
}

@media (prefers-reduced-motion: reduce) {
  .scroller { transition: none; }
  .scroller.is-fading { opacity: 1; }
}

/* ==========================================================================
   Desktop geometry, taken from the Figma frame (Desktop - 1, 1440 x 1343).
   Every value below is that frame's measurement expressed as a share of the
   viewport width, so the proportions hold as the window changes.

     panel      left 70.21%   width 29.79%
     gutter     40px          = 2.78vw
     nav        right edge 67.43%   top 5.83%
     name       13.47% -> 67.78%    top 14.31%
     role bar   13.47% -> 70.69%    top 23.82%   height 4.17%
     content    8.40% -> 67.36%     top 30.63%
     portrait   74.79% -> 97.08%    top 5.97%
     rule       73.26% -> 97.92%    at 26.56%
   ========================================================================== */

@media (min-width: 62rem) {
  /* Every value is the Figma measurement at 1440, expressed in vw so it
     scales down, and capped with min()/clamp() at its 1440 pixel value so the
     design never inflates past the frame it was drawn at on a wider screen. */
  :root { --gutter: min(2.78vw, 40px); }

  .masthead { padding-block-start: min(4.17vw, 4.468vh, 60px); }
  .masthead__bar { min-height: 0; }
  .brand svg { width: min(5.9vw, 85px); }

  /* Figma puts the logo and the nav on ONE row: logo y60..105, nav y84..111.
     Mine had the nav on its own line, which pushed everything below it down —
     that was the gap above the name. */
  /* One row, ordered from the reading start: nav, language switcher, logo.
     The logo takes the auto margin so it sits hard against the far edge, as
     Figma has it at x=60. The nav is a shade tighter than Figma's 775px
     because Figma has no language switcher and this design needs one. */
  .masthead__bar { flex-wrap: nowrap; align-items: flex-end; }
  .nav {
    flex: 0 0 auto;
    order: 1;
    min-width: 0;
    /* Figma has the nav 11px lower than a bottom-aligned row puts it
       (nav y84..111 against the logo's y60..105). Offset it visually so the
       row height — and everything measured from it — stays put. */
    position: relative;
    inset-block-start: min(0.76vw, 11px);
  }
  /* Held the switcher and the burger; the switcher is now fixed beside the
     accessibility button and the burger is mobile-only, so nothing is left. */
  .masthead__end { display: none; }
  .brand { order: 3; margin-inline-start: auto; margin-inline-end: min(1.39vw, 20px); }
  .nav__list {
    justify-content: flex-start;
    flex-wrap: nowrap;
    gap: 0 min(1.15vw, 17px);
  }
  .nav a { font-size: clamp(0.7rem, 0.83vw, 12px); white-space: nowrap; }

  /* Figma: name top 206, bar top 343, content top 441. */
  .masthead__id { padding-block-start: min(8.47vw, 3.084vh, 122px); }

  .name {
    font-size: min(8.6vw, 9.233vh, 124px);
    line-height: 1;
    letter-spacing: -0.02em;
  }
  .lang-he .name, .lang-ar .name { letter-spacing: 0; }
  .lang-ar .name { font-size: min(7.2vw, 7.744vh, 104px); }

  /* 824px slab: 13.47vw to the sand column's edge. */
  .role {
    display: block;
    width: min(56.74vw, 817px);
    margin-inline-start: calc(-1 * var(--gutter));
    margin-block-start: max(-0.83vw, -0.894vh, -12px);
    padding-block: min(1.08vw, 1.154vh, 15.5px);
    padding-inline: min(1.2vw, 17px);
    font-size: clamp(0.85rem, min(1.55vw, 1.787vh), 24px);
    line-height: 1.3;
    /* Logical, not padding-left: the physical property lands on the far side
       in Hebrew and Arabic, so it aligned the sentence under the name in
       English only. */
    padding-inline-start: 4.5%;
  }

  .scroller { padding-block-start: min(2.64vw, 2.829vh, 38px); }
  /* Prose keeps a readable measure; the list sections take the full column
     and run in two tracks, so they use width instead of height — that is what
     lets them fit without scrolling or shrinking into illegibility. */
  .sec__body { max-width: min(59vw, 850px); }
  .roles, .degrees, .areas { max-width: none; }
  .roles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1em 2em; }
  .degrees { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.7em 2em; }
  /* Six areas in two tracks: three rows of two. */
  .areas { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9em 1.6em; }
  .sec__body:has(.roles), .sec__body:has(.degrees), .sec__body:has(.areas) { max-width: none; }

  /* One base size on the section; everything inside is em-relative to it, so
     the fit routine can scale a whole section with a single property. */
  .sec { font-size: clamp(0.95rem, 1.46vw, 21px); }
  .sec__body { font-size: 1em; gap: 0.76em; }
  .sec__body p { line-height: 1.55; }
  .lead { font-size: 1em; font-weight: 400; line-height: 1.55; }
  .area__text, .job__text, .degree__text, .award__line { font-size: 0.81em; }
  .area__title, .job__title, .degree__title, .degrees__note, .award__src { font-size: 0.9em; }
  .job__years { font-size: 0.78em; }
  .areas { gap: 0.9em 1.4em; }
  .roles { gap: 1.2em; }
  .degrees { gap: 1.7em; }
  .awards { gap: 0.9em; }

  /* Panel: portrait top 86, height 296; the rule sits on its bottom edge and
     is WIDER than the portrait — Figma 1055..1410 vs portrait 1077..1398. */
  /* Only enough top padding to keep the top of his head off the window edge —
     the portrait's position is set by aligning its rule to the role bar
     (site.js writes --rule-shift), and every pixel of padding here is a pixel
     the portrait cannot use. */
  .panel { padding: clamp(14px, 2.4vh, 32px) 0 min(2.8vw, 2.978vh, 40px); }
  .panel__top {
    position: relative;
    padding-block-start: 0;
    margin-block-end: 0;
    /* Set by site.js so the rule under the portrait lands exactly on the
       bottom edge of the role bar in the other column. The two columns are
       laid out independently and each language sets the bar at a slightly
       different height, so this cannot be a fixed CSS value. */
    margin-block-start: var(--rule-shift, 0px);
  }
  .panel__portrait {
    width: min(22.29vw, 23.902vh, 321px);
    max-width: none;
    border: 0;
    margin-inline: auto;
  }
  /* Vector 1 — the rule on the portrait's bottom edge. Figma runs it
     1055..1410, wider than the portrait's own 1077..1398. Centring is
     symmetric, so physical left/transform is correct in both directions. */
  .panel__top::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    /* site.js keeps this in proportion with the portrait it underlines. */
    width: var(--rule-w, min(24.65vw, 26.433vh, 355px));
    height: 2px;
    background: var(--sand);
    opacity: 1.6;
  }

  .panel__section { font-size: clamp(0.95rem, 1.15vw, 17px); }
  .panel__foot { gap: clamp(0.8rem, 1.2vw, 17px); }
}


/* Height-aware desktop ------------------------------------------------------
   The Figma frame is 1440x1343 — much taller than a real laptop window. Every
   vertical value above therefore carries a vh term alongside its vw term, each
   set so that AT 1343px of viewport height it resolves to exactly the Figma
   pixel value, and below that the masthead scales down with the window. That
   is what keeps the longest sections (English "experience") fitting without a
   scrollbar on a short screen, instead of being squeezed into illegibility by
   a masthead drawn for a 1343px page. The px value caps it so a taller window
   never inflates the design past the frame it was drawn at. */


/* Legal strip — sits below the panel, outside the area that must fit. */
.legal {
  flex: 0 0 auto;
  display: grid;
  gap: 0.15rem;
  padding: 0.6rem var(--gutter) 0.8rem;
  border-block-start: 1px solid var(--line-on-sand-soft);
  font-size: 0.7rem;
  line-height: 1.45;
  color: var(--on-sand-muted);
  max-width: none;
}
