/*
  THE LANDING PAGE'S ONE STYLESHEET, hand-written: no Tailwind and no build step, because the page is
  a logo, two doors and a language row, and a toolchain to produce that would be most of the
  repository's surface for none of its benefit.

  THE TOKENS BELOW ARE COPIED, NOT IMPORTED, from frontend/src/index.css (master at 2576129a, the
  design level two merge): the colour palette and both dark blocks value for value (their long
  comments live there), the design system's numbers this page uses, the Arabic face rule, the focus
  ring and the logo's theme switch. It is the
  consoles' own rule - they duplicate rather than share, and keep the copies identical - and it has
  the consoles' cost: A PALETTE CHANGE MADE IN THE CONSOLES MUST BE MADE HERE TOO. Nothing fails if
  it is not; tests/test_landing_page.py checks this file's contrast, not its agreement with the
  consoles (a backend test reading frontend/src/index.css would be skipped by CI's path filter for
  exactly the commit that changes it - see tests/test_ci_path_filter.py).

  THE THEME FOLLOWS THE SYSTEM, AS IN THE CONSOLES, and there is no switch, because the consoles have
  none: no code anywhere sets data-theme. The [data-theme] selectors are kept anyway so the blocks
  stay word for word the consoles' and the day a switch arrives it reaches this page by copying.
*/

/* --- fonts -----------------------------------------------------------------------------------------
  SELF-HOSTED, the consoles' faces at the weights this page draws: Fraunces 600 for Latin headings,
  IBM Plex Sans Arabic 400 and 600 for every Arabic word. Copied from @fontsource 5.3.0 (the version
  frontend/package-lock.json pins) with their unicode-range lines, so a browser fetches only the
  subsets the page in front of it needs; fonts/OFL-*.txt are the licences the files ship under.
  Latin body text is the system face, as it is in the consoles (Tailwind's default sans stack).
  A REPLACED FONT FILE NEEDS A NEW NAME: nginx serves /fonts/ as immutable for a year. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/fonts/fraunces-latin-ext-600-normal.woff2) format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/fonts/fraunces-latin-600-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/fonts/ibm-plex-sans-arabic-arabic-400-normal.woff2) format('woff2');
  unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EE03,U+1EE05-1EE1F,U+1EE21-1EE22,U+1EE24,U+1EE27,U+1EE29-1EE32,U+1EE34-1EE37,U+1EE39,U+1EE3B,U+1EE42,U+1EE47,U+1EE49,U+1EE4B,U+1EE4D-1EE4F,U+1EE51-1EE52,U+1EE54,U+1EE57,U+1EE59,U+1EE5B,U+1EE5D,U+1EE5F,U+1EE61-1EE62,U+1EE64,U+1EE67-1EE6A,U+1EE6C-1EE72,U+1EE74-1EE77,U+1EE79-1EE7C,U+1EE7E,U+1EE80-1EE89,U+1EE8B-1EE9B,U+1EEA1-1EEA3,U+1EEA5-1EEA9,U+1EEAB-1EEBB,U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(/fonts/ibm-plex-sans-arabic-latin-400-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/fonts/ibm-plex-sans-arabic-arabic-600-normal.woff2) format('woff2');
  unicode-range: U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EE03,U+1EE05-1EE1F,U+1EE21-1EE22,U+1EE24,U+1EE27,U+1EE29-1EE32,U+1EE34-1EE37,U+1EE39,U+1EE3B,U+1EE42,U+1EE47,U+1EE49,U+1EE4B,U+1EE4D-1EE4F,U+1EE51-1EE52,U+1EE54,U+1EE57,U+1EE59,U+1EE5B,U+1EE5D,U+1EE5F,U+1EE61-1EE62,U+1EE64,U+1EE67-1EE6A,U+1EE6C-1EE72,U+1EE74-1EE77,U+1EE79-1EE7C,U+1EE7E,U+1EE80-1EE89,U+1EE8B-1EE9B,U+1EEA1-1EEA3,U+1EEA5-1EEA9,U+1EEAB-1EEBB,U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(/fonts/ibm-plex-sans-arabic-latin-600-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* --- the palette: frontend/src/index.css's three token blocks, value for value ------------------- */
:root {
  color-scheme: light;
  --color-ink: #0b1628;
  --color-paper: #f3f5f8;
  --color-petrol: #1a3a5c;
  --color-petrol-strong: #122844;
  --color-brass: #b8863b;
  --color-moss: #059669;
  --color-moss-strong: #065f46;
  --color-brick: #b4453f;

  --color-bg: var(--color-paper);
  --color-surface: #ffffff;
  --color-surface-2: #e6eaf0;
  --color-border: #d0d7e2;
  --color-text: var(--color-ink);
  --color-text-muted: #4b5565;
  --color-text-faint: #626976;

  --color-accent: var(--color-petrol);
  --color-accent-strong: var(--color-petrol-strong);
  --color-brass-fg: #8a621f;
  --color-moss-fg: #047857;
  --color-brick-fg: #8f2f2a;
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --color-bg: var(--color-ink);
  --color-surface: #152033;
  --color-surface-2: #1c2b40;
  --color-border: #2a3d58;
  --color-text: #f3f5f8;
  --color-text-muted: #b8c0cc;
  --color-text-faint: #8b95a5;

  --color-accent-strong: var(--color-paper);
  --color-brass-fg: #dcae63;
  --color-moss-fg: #34d399;
  --color-brick-fg: #e28782;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    /* The same as the data-theme block above; the two dark blocks must not drift. */
    color-scheme: dark;
    --color-bg: var(--color-ink);
    --color-surface: #152033;
    --color-surface-2: #1c2b40;
    --color-border: #2a3d58;
    --color-text: #f3f5f8;
    --color-text-muted: #b8c0cc;
    --color-text-faint: #8b95a5;

    --color-accent-strong: var(--color-paper);
    --color-brass-fg: #dcae63;
    --color-moss-fg: #34d399;
    --color-brick-fg: #e28782;
  }
}

/* --- the design system's numbers this page uses (DESIGN.md, "Design system") -------------------- */
:root {
  --font-display: 'Fraunces', ui-serif, Georgia, serif;
  --font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  --font-arabic: 'IBM Plex Sans Arabic', ui-sans-serif, system-ui, sans-serif;

  --text-display: 28px;
  --text-display--line-height: 36px;
  --text-section: 16px;
  --text-section--line-height: 24px;
  --text-body: 14px;
  --text-body--line-height: 22px;
  --text-cell: 13px;
  --text-cell--line-height: 20px;
  --text-label: 12px;
  --text-label--line-height: 18px;

  --spacing-page: 24px;
  --spacing-cards: 16px;
  --spacing-card: 16px;
  --spacing-fields: 12px;
  --spacing-tap: 44px;

  --radius-control: 8px;
  --radius-card: 12px;
  --radius-phone-card: 16px;

  --container-prose: 80ch;
  /* The staff sign-in card's width (LoginPage, max-w-[29rem]), so the two pages line up. */
  --container-column: 29rem;
}

/* ARABIC, BY THE DOCUMENT'S OWN lang - the consoles' rule. Headings drop Fraunces, which has no
   Arabic glyphs, by overriding the token rather than the elements. */
html:lang(ar) {
  --font-display: var(--font-arabic);
}

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

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--text-body--line-height);
  font-variant-numeric: tabular-nums;
}

html:lang(ar) body {
  font-family: var(--font-arabic);
}

/* "العربية" on an English or Turkish page is the one Arabic word there; without this it falls to
   whatever Arabic face the system has, beside a page whose Arabic is otherwise always Plex. */
.language:lang(ar) {
  font-family: var(--font-arabic);
}

h1,
h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  text-wrap: balance;
}

p {
  margin: 0;
}

/* NOTHING IS DRAWN WHILE A STORED LANGUAGE IS ON ITS WAY IN. language.js marks <html> in <head>
   for a reader whose stored choice is English or Turkish, and landing.js lifts the mark once those
   words are in, so that reader sees the page's background and then their own language - never the
   Arabic written into index.html. visibility rather than display, so the layout is already done
   and nothing moves when it is shown.
   AND THE HOLD LETS GO BY ITSELF AFTER FOUR SECONDS. If landing.js never runs - a dropped request,
   a script blocked by an extension - a page held like this would stay blank for good; this way it
   shows, in the wrong words, rather than as nothing. Four seconds is past landing.js's arrival on
   the 3G throttle the review used (about 1.5 s), so only a broken load should ever reach it. */
html[data-language-pending] .shell {
  visibility: hidden;
  animation: language-pending-gives-up 0s linear 4s forwards;
}

@keyframes language-pending-gives-up {
  to {
    visibility: visible;
  }
}

/* THE `hidden` ATTRIBUTE MUST WIN. The partners block is a grid when shown; a display rule of its
   own would otherwise beat the user-agent's [hidden] and draw the hidden doors for everybody. */
[hidden] {
  display: none !important;
}

/* --- the shell: one column, and the navy panel at the web width ------------------------------- */
.shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  /* THE NOTCH, SIDEWAYS - physical on purpose, as in the consoles: the notch is on the glass's left
     or right whatever the language. */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

.main {
  display: flex;
  flex: 1 0 auto;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 16px;
}

.column {
  width: 100%;
  max-width: var(--container-column);
}

/* A PHONE STARTS AT THE TOP, under the status bar, as the staff sign-in does: centring a short page
   on a tall phone puts the doors where a thumb has to reach up for them. */
@media (max-width: 767.98px) {
  .main {
    justify-content: flex-start;
    padding-top: max(32px, env(safe-area-inset-top));
    padding-bottom: var(--spacing-page);
  }
}

/* --- the logo ------------------------------------------------------------------------------------
  THE PRESS-AND-HOLD TARGET (landing.js), so nothing the browser does on a long press may fight it:
  no image callout or save menu (iOS), no text selection or magnifier, no drag of the image (a drag
  is a pointercancel, which would end the hold), and no panning that starts here - a pan is a
  pointercancel too. The images take no pointer events, so the wrapper is always the target. */
.brand {
  display: inline-flex;
  flex-shrink: 0;
  max-width: 100%;
  margin-bottom: var(--spacing-page);
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
}

/* THE LOCKUP FOLLOWS <html lang>, which language.js sets in <head> for a returning English or
   Turkish reader and landing.js sets on every switch - so the right file is chosen before the first
   paint and a switch waits for no download (index.html says why all four files are in the page).
   ON THE WRAPPERS, NOT THE IMAGES: a language rule on the images would have to outrank the theme
   rules below, whose display: block for the dark file is (0,3,0) - exactly the specificity trap
   the next comment records - while display: none on a wrapper hides both its files whatever the
   theme rules say. pointer-events: none, like the images, so the hold's target stays .brand. */
.brand-lockup {
  display: inline-flex;
  max-width: 100%;
  pointer-events: none;
}

html:lang(ar) .brand-lockup-latin,
html:not(:lang(ar)) .brand-lockup-arabic {
  display: none;
}

/* NO `display` HERE. The first version said display: block, which outranks the bare
   .brand-logo-dark { display: none } below (an element selector beats none), so the light theme drew
   BOTH files: the dark lockup's paper wordmark vanished into the page and its light-brass half-mark
   hung beside the logo. The images are flex items, blockified already. */
.brand img {
  height: 40px;
  width: auto;
  max-width: 100%;
  pointer-events: none;
  -webkit-user-drag: none;
}

@media (min-width: 768px) {
  .brand img {
    height: 48px;
  }
}

/* THE SOLIDUS LOGO FOLLOWS THE THEME, by the same selectors the tokens use and no others - the
   consoles' four rules, verbatim. A <picture> with a prefers-color-scheme source cannot see
   data-theme. */
.brand-logo-dark {
  display: none;
}

:root[data-theme='dark'] .brand-logo-light {
  display: none;
}

:root[data-theme='dark'] .brand-logo-dark {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .brand-logo-light {
    display: none;
  }

  :root:not([data-theme='light']) .brand-logo-dark {
    display: block;
  }
}

/* --- the words above the doors ------------------------------------------------------------------- */
.heading {
  font-size: var(--text-display);
  line-height: var(--text-display--line-height);
  color: var(--color-text);
}

.lede {
  margin-top: 8px;
  color: var(--color-text-muted);
  max-width: var(--container-prose);
}

/* --- the doors ---------------------------------------------------------------------------------- */
.doors-nav {
  margin-top: var(--spacing-page);
}

.doors {
  display: grid;
  gap: var(--spacing-fields);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* THE WHOLE CARD IS THE LINK, so the target is the card and not the words on it - 76px tall at the
   least, well over the 44px a thumb needs. NAMED BY EVERYTHING ON IT, title then line, and not by the
   title alone: an aria-labelledby on the title was the first version, and axe refused it in English
   and Turkish (label-content-name-mismatch, WCAG 2.5.3) - a name that leaves out words the card
   shows breaks voice control, which matches what is said against what is seen. */
.door {
  display: flex;
  align-items: center;
  gap: var(--spacing-card);
  min-height: 76px;
  padding: var(--spacing-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  /* DESIGN.md rule 7: hover and focus feedback only, and no longer than 150ms. */
  transition: background-color 150ms ease, border-color 150ms ease;
}

@media (max-width: 767.98px) {
  .door {
    border-radius: var(--radius-phone-card);
  }
}

/* :hover ONLY WHERE THERE IS A HOVER - the consoles' rule: a touch screen keeps :hover after a tap,
   which would leave the door just tapped looking selected while the next page loads. */
@media (hover: hover) {
  .door:hover {
    border-color: var(--color-accent);
    background: var(--color-surface-2);
  }

  .language:hover {
    color: var(--color-text);
  }
}

/* PETROL IS INVISIBLE ON THE DARK SURFACES (1.2-1.6:1), so the hover edge takes accent-strong -
   paper - there, by the token blocks' two selectors; light keeps petrol. The consoles' edge rule. */
@media (hover: hover) {
  :root[data-theme='dark'] .door:hover {
    border-color: var(--color-accent-strong);
  }
}

@media (hover: hover) and (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .door:hover {
    border-color: var(--color-accent-strong);
  }
}

.door-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-control);
  /* accent-strong rather than accent, for the tile and the glyph: petrol-strong in light, paper in
     dark. A petrol tint vanished into the dark surface and a petrol glyph on it read about 1.4:1,
     under the 3:1 a meaningful glyph needs; paper at 8% is a tile you can see, and paper on it
     reads above 10:1. */
  background: color-mix(in srgb, var(--color-accent-strong) 8%, var(--color-surface));
  color: var(--color-accent-strong);
}

.door-text {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.door-title {
  font-family: var(--font-display);
  font-size: var(--text-section);
  line-height: var(--text-section--line-height);
  font-weight: 600;
  color: var(--color-text);
}

.door-line {
  font-size: var(--text-cell);
  line-height: var(--text-cell--line-height);
  color: var(--color-text-muted);
}

.door-chevron {
  flex-shrink: 0;
  color: var(--color-text-muted);
}

/* The chevron points the way the page reads: forward is left in Arabic. */
[dir='rtl'] .door-chevron {
  transform: scaleX(-1);
}

/* --- the hidden doors ---------------------------------------------------------------------------- */
.partners {
  margin-top: var(--spacing-page);
}

.partners-title {
  margin-bottom: var(--spacing-fields);
  font-family: inherit;
  font-size: var(--text-label);
  line-height: var(--text-label--line-height);
  font-weight: 600;
  color: var(--color-text-muted);
}

/* --- the language row ---------------------------------------------------------------------------- */
.languages {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  margin-top: var(--spacing-page);
}

.language {
  min-height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--color-text-muted);
  font: inherit;
  font-size: var(--text-cell);
  line-height: var(--text-cell--line-height);
  cursor: pointer;
}

/* THE CURRENT ONE BY WEIGHT AND COLOUR, never colour alone (rule 5), and aria-pressed for a reader. */
.language[aria-pressed='true'] {
  font-weight: 600;
  color: var(--color-text);
}

/* 44px TO PRESS ON A PHONE (DESIGN.md, "Touch targets on a phone are at least 44"). */
@media (max-width: 767.98px) {
  .language {
    min-width: var(--spacing-tap);
    min-height: var(--spacing-tap);
  }
}

.noscript {
  margin-top: var(--spacing-fields);
  text-align: center;
  font-size: var(--text-cell);
  line-height: var(--text-cell--line-height);
  color: var(--color-brass-fg);
}

/* --- the note: a quiet line on a phone and a tablet, the navy panel on the web ------------------ */
.panel {
  display: flex;
  justify-content: center;
  padding: 0 16px max(var(--spacing-page), env(safe-area-inset-bottom));
}

.note {
  max-width: var(--container-column);
  font-size: var(--text-cell);
  line-height: var(--text-cell--line-height);
  color: var(--color-text-muted);
  text-align: center;
}

/* AT 1180 AND WIDER, THE STAFF SIGN-IN'S PICTURE: the column on the start side and the navy panel
   on the end side, the note at its foot. petrol-strong with paper, not accent-strong - that token
   turns to paper in the dark theme, and both of these keep their value in either. */
@media (min-width: 1180px) {
  .shell {
    flex-direction: row;
  }

  .panel {
    flex: 0 0 51%;
    flex-direction: column;
    justify-content: flex-end;
    padding: 48px;
    background: var(--color-petrol-strong);
  }

  .note {
    max-width: var(--container-prose);
    color: var(--color-paper);
    text-align: start;
  }
}

/* --- focus: frontend/src/index.css's two rules, verbatim (DESIGN.md rule 10) ---------------------
  Petrol in light; paper (accent-strong) in dark, where petrol reads 1.2-1.6:1 on the surfaces. */
:where(a, button, input, select, textarea, summary, [role='button'], [role='tab'], [tabindex]):focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

:root[data-theme='dark'] :where(a, button, input, select, textarea, summary, [role='button'], [role='tab'], [tabindex]):focus-visible {
  outline-color: var(--color-accent-strong);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) :where(a, button, input, select, textarea, summary, [role='button'], [role='tab'], [tabindex]):focus-visible {
    outline-color: var(--color-accent-strong);
  }
}

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