/* The foundation both non-staff surfaces are built on: the typefaces, the
   tokens, the reset, and every idiom /p and /e share — chrome, cards, forms,
   buttons, messages, empty states. Each surface then links one more file for
   what is its own. The staff console links neither; it keeps app.css.

   Mobile first. Nothing here may assume a pointer, a wide viewport, or a
   principal. */

@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/static/fonts/literata-greek-600-normal.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/static/fonts/literata-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: 'Commissioner';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/static/fonts/commissioner-greek-400-normal.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: 'Commissioner';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/static/fonts/commissioner-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: 'Commissioner';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/static/fonts/commissioner-greek-600-normal.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: 'Commissioner';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/static/fonts/commissioner-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 Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/static/fonts/ibm-plex-mono-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;
}

:root {
  --ink: #14263C;
  --shore: #F6F3EC;
  --surface: #FFFFFF;
  --haze: #E4E9EC;
  --sea: #2D6E8D;
  --honey: #C58B27;

  /* The company's own blue. It is not one of the palette's colours and it is
     not being made into one: the mark is drawn in it and the manifest names it
     as the theme, and nothing else on either surface may use it until the
     palette and the brand are reconciled deliberately. */
  --brand: #446fb6;

  --olive: #3E7C4F;
  --clay: #8A4A44;

  --quiet: rgba(20, 38, 60, 0.64);
  --title: 'Literata', Georgia, serif;
  --body: 'Commissioner', system-ui, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
  --radius: 10px;
  --gap: 1rem;

  /* One shadow on the whole product. A card is a sheet a millimetre above the
     shore, not a floating panel: the near shadow gives it an edge, the far one
     gives it weight, and nothing else on either surface casts anything. */
  --lift: 0 1px 1px rgba(20, 38, 60, 0.04), 0 10px 22px -14px rgba(20, 38, 60, 0.28);
}

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

body {
  margin: 0;
  background: var(--shore);
  color: var(--ink);
  font: 400 16px/1.55 var(--body);
  -webkit-text-size-adjust: 100%;
}

/* ---- chrome: the signed-in bar ---- */

.top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--haze);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font: 600 1.15rem/1 var(--title);
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}

/* The mark, where the honey bead used to stand. The bead was a placeholder for
   a logo the product did not have yet; it has one now, and the wordmark is the
   mark plus the name set in the title face. */
.wordmark .mark {
  height: 28px;
  width: auto;
  fill: var(--brand);
  flex: none;
}

.langs { display: flex; gap: 0.35rem; }

.langs a {
  padding: 0.4rem 0.5rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--quiet);
  text-decoration: none;
  border-radius: 6px;
}

.langs a:hover { color: var(--sea); background: var(--shore); }

.top form { margin: 0; }

/* ---- chrome: the front door ----

   Where the bar is chrome, this is a first impression: the wordmark at display
   size, one sentence saying what the surface is for, and a rule with a bead on
   it — the strand starting at the top of the page and running down through the
   surface's own signature below. */

.masthead {
  position: relative;
  max-width: 460px;
  margin: 0 auto;
  padding: clamp(1.75rem, 5vh, 3.25rem) 1rem 1.5rem;
}

.masthead .langs { justify-content: flex-end; margin-bottom: 1.5rem; }

.masthead .eyebrow {
  margin: 0 0 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--sea);
}

.masthead .wordmark {
  display: flex;
  gap: 0.55rem;
  margin: 0 0 0.5rem;
  font-size: clamp(2.1rem, 1.55rem + 2.6vw, 2.6rem);
  letter-spacing: -0.025em;
}

.masthead .wordmark .mark { height: 44px; }

.masthead .claim {
  margin: 0;
  max-width: 32ch;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--quiet);
}

/* The rule the masthead sits on, and the bead threaded through it under the
   start of the wordmark. The shore ring is what parts the hairline. The bead
   stays honey: it belongs to the journey thread the surface is strung from,
   not to the logo that now stands above it. */
.masthead::after {
  content: '';
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 0;
  height: 1px;
  background: var(--haze);
}

/* Above the rule: the hairline is the masthead's own ::after and so paints
   later, and without this it draws straight across the bead. */
.masthead .wordmark::after {
  content: '';
  position: absolute;
  z-index: 1;
  left: 1rem;
  bottom: -4.5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--honey);
  box-shadow: 0 0 0 4px var(--shore);
}

main {
  max-width: 640px;
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
}

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

h1 {
  font: 600 clamp(1.8rem, 1.35rem + 2.2vw, 2.3rem)/1.15 var(--title);
  margin: 0 0 0.85rem;
  letter-spacing: -0.02em;
}

/* Section heads take their contrast from the face, not from capitals: Literata
   against a Commissioner body is a bigger step than any size change, and it
   keeps the two roles the product already has. */
h2 {
  font: 600 1.2rem/1.3 var(--title);
  margin: 1.85rem 0 0.85rem;
  letter-spacing: -0.01em;
}

p { margin: 0 0 0.75rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--sea); text-underline-offset: 3px; }

.lede { color: var(--quiet); margin-bottom: 1.2rem; font-size: 1.03rem; }
.hint { color: var(--quiet); font-size: 0.9rem; }
/* A hint inside a label is a note about the field, not a second label: without
   this it inherits the label's 600 and reads as loud as the thing it explains. */
label > .hint { font-weight: 400; }
.mono { font-family: var(--mono); font-size: 0.92em; }
/* The way back is a tap target like any other. The class is worn by the link
   itself on one surface and by the paragraph around it on the other, so both
   selectors are here and only the inner one is ever the thing tapped. */
.back { display: inline-flex; align-items: center; min-height: 44px; margin: 0 0 0.25rem; font-size: 0.9rem; }
.back > a { display: inline-flex; align-items: center; min-height: 44px; }

/* ---- cards ---- */

.card {
  background: var(--surface);
  border: 1px solid var(--haze);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  padding: 1.3rem 1.2rem;
  margin-bottom: var(--gap);
}

.card > h2:first-child, .card > h1:first-child { margin-top: 0; }

/* The page's own work, marked at its top edge. Sea is the colour of an action
   the page wants; honey stays reserved for a decision somebody is asking of
   the reader, which is why the consent card and nothing else carries it. */
.card-lead { border-top: 3px solid var(--sea); }

.stack { list-style: none; margin: 0; padding: 0; }
.stack > li + li { margin-top: var(--gap); }

/* ---- rows: a list of things, one card each ---- */

.row {
  background: var(--surface);
  border: 1px solid var(--haze);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  padding: 1.05rem 1.1rem;
}

.row h3 {
  font: 600 1.1rem/1.3 var(--title);
  margin: 0 0 0.15rem;
  letter-spacing: -0.01em;
}

.row h3 a { text-decoration: none; }
.row h3 a:hover { text-decoration: underline; }

.row dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.7rem;
  margin: 0.55rem 0 0;
  font-size: 0.9rem;
}

.row dt { color: var(--quiet); }
.row dd { margin: 0; }

.facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.9rem;
  margin: 0 0 1rem;
  font-size: 0.95rem;
}

.facts dt { color: var(--quiet); }
.facts dd { margin: 0; }

.tag {
  display: inline-block;
  margin-top: 0.6rem;
  padding: 0.2rem 0.55rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--olive);
  background: rgba(62, 124, 79, 0.09);
  border-radius: 999px;
}

/* ---- forms ---- */

label { display: block; margin: 0 0 0.9rem; font-size: 0.9rem; font-weight: 600; }

label input,
label select { margin-top: 0.3rem; }

/* Every text-shaped input, whatever its type: a field that opts out of this
   by carrying a type nobody listed renders half-width beside its label. */
input:not([type="checkbox"]):not([type="radio"]), select {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 0.6rem 0.7rem;
  font: 400 16px/1.4 var(--body);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--haze);
  border-radius: 8px;
}

select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--quiet) 50%),
                    linear-gradient(135deg, var(--quiet) 50%, transparent 50%);
  background-position: right 1.05rem center, right 0.75rem center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2rem;
}

input[type="file"] { padding: 0.55rem 0.7rem; }

/* The shadow button is the browser's, and so is the "no file chosen" beside it
   — but its shape is ours, and left native it is the one control on the
   surface that belongs to another design. */
input[type="file"]::file-selector-button {
  margin: 0 0.7rem 0 0;
  padding: 0.4rem 0.85rem;
  font: 600 0.9rem/1.2 var(--body);
  color: var(--sea);
  background: var(--surface);
  border: 1.5px solid var(--sea);
  border-radius: 8px;
  cursor: pointer;
}

input[type="file"]::file-selector-button:hover { background: #EEF4F7; }

.check {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  margin: 0 0 0.3rem;
  font-weight: 400;
}

.check input { width: 22px; height: 22px; min-height: 0; margin: 0; flex: none; accent-color: var(--sea); }

fieldset {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.85rem 0.4rem;
  border: 1px solid var(--haze);
  border-radius: 8px;
}

legend { padding: 0 0.35rem; font-size: 0.9rem; font-weight: 600; }

/* No radius here: changing one on focus moves the shape under the ring.
   The honey alone is 2.96:1 on white and 2.67:1 on the shore, under the 3:1
   floor a focus indicator has to clear, so a 1px ink line closes it from the
   outside: the surface shadow fills the offset gap, the ink one shows past the
   outline's outer edge. */
:focus-visible {
  outline: 2px solid var(--honey);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 5px var(--ink);
}

button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.6rem 1.15rem;
  font: 600 1rem/1.2 var(--body);
  color: var(--surface);
  background: var(--sea);
  border: 1.5px solid var(--sea);
  border-radius: 8px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

button:hover, .btn:hover { background: #255d78; border-color: #255d78; }

.btn-secondary {
  color: var(--sea);
  background: var(--surface);
  border-color: var(--sea);
}

.btn-secondary:hover { background: #EEF4F7; border-color: var(--sea); color: var(--sea); }

.btn-danger {
  color: var(--clay);
  background: var(--surface);
  border-color: var(--clay);
}

.btn-danger:hover { background: #FAF2F1; border-color: var(--clay); color: var(--clay); }

.actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.9rem; }
.actions form { margin: 0; flex: 1 1 9rem; }
.actions form button { width: 100%; }
.actions > button { flex: 1 1 9rem; }

/* ---- messages ---- */

.notice {
  margin: 0 0 0.9rem;
  padding: 0.65rem 0.8rem;
  font-size: 0.94rem;
  color: var(--olive);
  background: rgba(62, 124, 79, 0.07);
  border-left: 3px solid var(--olive);
  border-radius: 0 8px 8px 0;
}

.error {
  margin: 0 0 0.9rem;
  padding: 0.65rem 0.8rem;
  font-size: 0.94rem;
  color: var(--clay);
  background: rgba(138, 74, 68, 0.07);
  border-left: 3px solid var(--clay);
  border-radius: 0 8px 8px 0;
}

/* «Check the fields marked below» has to mark them: a label carrying an error
   colours its own control's border. The :not() pair matches the base rule's
   specificity so this wins on top of it, not by source order. */
label:has(> .error) input:not([type="checkbox"]):not([type="radio"]),
label:has(> .error) select {
  border-color: var(--clay);
}

/* The checkbox group is the one field whose error hangs off the fieldset
   rather than a label, and it is a field the banner counts too. */
fieldset:has(> .error) { border-color: var(--clay); }

/* A language and its level are one thing on two controls, so they sit on one
   line and wrap together on a narrow screen. The labels are for screen readers
   only: repeating «Γλώσσα» and «Επίπεδο» six times down the page is noise for
   everybody who can see the legend, and a placeholder alone is not a label. */
.lang-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
}

.lang-row input { flex: 2 1 9rem; margin: 0; }
.lang-row select { flex: 1 1 8rem; margin: 0; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* An inline field error sits under its own input, in the same red-brown. */
label .error, fieldset .error {
  display: block;
  margin: 0.3rem 0 0;
  padding: 0;
  background: none;
  border: 0;
  font-size: 0.86rem;
  font-weight: 400;
}

/* An invitation to do something, above content that is already there. */
.prompt {
  margin: 0 0 1rem;
  padding: 0.8rem 0.9rem;
  font-size: 0.94rem;
  background: var(--surface);
  border: 1px solid var(--haze);
  border-left: 3px solid var(--honey);
  border-radius: 0 8px 8px 0;
}

/* ---- empty states ----

   An empty page is an invitation, and the invitation is drawn: a cord with
   four beads on it and a fifth in honey at the end — the strand this product
   is named for, waiting for what comes next. No image file, no icon font, one
   pseudo-element. */

.empty {
  background: var(--surface);
  border: 1px dashed var(--haze);
  border-radius: var(--radius);
  padding: 1.9rem 1.2rem;
  text-align: center;
}

.empty::before {
  content: '';
  display: block;
  width: 138px;
  height: 14px;
  margin: 0 auto 1.25rem;
  background:
    radial-gradient(circle 6px at 131px 7px, var(--honey) 0 5.4px, transparent 6px),
    radial-gradient(circle 5px at 100px 7px, var(--haze) 0 4.4px, transparent 5px),
    radial-gradient(circle 5px at 69px 7px, var(--haze) 0 4.4px, transparent 5px),
    radial-gradient(circle 5px at 38px 7px, var(--haze) 0 4.4px, transparent 5px),
    radial-gradient(circle 5px at 7px 7px, var(--haze) 0 4.4px, transparent 5px),
    linear-gradient(var(--haze), var(--haze));
  background-repeat: no-repeat;
  background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 7px 6.5px;
  background-size: auto, auto, auto, auto, auto, 124px 1px;
}

.empty p { margin: 0 0 1rem; color: var(--quiet); }
.empty .btn { min-width: 12rem; }

/* ---- signed-out pages: one form or one message ---- */

.single { max-width: 460px; }
.single .card form button { width: 100%; }

/* Under a display wordmark the page title is the second voice, not a second
   masthead. */
.single h1 {
  font-size: clamp(1.4rem, 1.2rem + 1vw, 1.7rem);
  margin-bottom: 0.9rem;
}

/* The way off a signed-out page — create an account, forgot your password,
   back to login — is a tap target like any other, not 22px of text. */
.single p.hint > a {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
}

.card.center { text-align: center; }

/* A message card is one idiom and renders at one size, signed in or out. Its
   h1 is a sentence rather than a page title, and at the page scale a signed-in
   reader got it three lines tall where a signed-out one got two. */
.card.center h1 { font-size: clamp(1.4rem, 1.2rem + 1vw, 1.7rem); }
.card.center p { color: var(--quiet); }
.card.center form { margin-top: 1.1rem; }
.card.center .btn { min-width: 11rem; }

@media (max-width: 400px) {
  main { padding: 1.25rem 0.85rem 2.5rem; }
  .card, .row { padding: 1.1rem 0.95rem; }
  .masthead { padding-left: 0.85rem; padding-right: 0.85rem; }
  .masthead::after { left: 0.85rem; right: 0.85rem; }
  .masthead .wordmark::after { left: 0.85rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
