/* =========================================================================
   Saydali — "apothecary editorial"
   -------------------------------------------------------------------------
   The audience is pharmacy owners deciding whether to hand a stranger their
   keys, so the design commits to credibility rather than flair: an editorial
   serif carrying the name at display size, a spec-sheet treatment for the
   practical facts, warm paper tones, and exactly one accent — the green of a
   Belgian pharmacy cross. All character comes from type and composition; there
   are no effects to age badly.

   Sections: tokens · base · layout · header · hero · sections · facts ·
             faq · calendar · contact · footer · credit · motion
   ========================================================================= */

/* ---------- fonts ------------------------------------------------------ */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/fraunces-latin.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: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/fraunces-latin-ext.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: 'Karla';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/fonts/karla-latin.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: 'Karla';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/fonts/karla-latin-ext.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;
}

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

:root {
  --paper: #f5f2ea;
  --surface: #fbf9f4;
  --tint: #efece2;
  --ink: #17211d;
  --ink-soft: #55635c;
  --line: #ddd8ca;
  --accent: #1b6b4e;
  --accent-ink: #ffffff;
  --accent-wash: #e2ece6;
  --warn: #8a4b1f;
  --warn-wash: #f6e8d8;
  --error: #8f2f2a;

  /* Calendar states. Text-on-fill measures 7.21:1 (busy) and 6.44:1 (free). */
  --cal-busy-bg: #f7dcd8;
  --cal-busy-ink: #7d2b26;
  --cal-busy-line: #eec4be;
  --cal-free-bg: #dcecdf;
  --cal-free-ink: #1b5c42;
  --cal-free-line: #c3ddc9;
  --cal-past-ink: #9aa39d;

  --display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --body: 'Karla', 'Helvetica Neue', Arial, sans-serif;

  --shell: 68rem;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --rhythm: clamp(3.5rem, 9vw, 7rem);
  --radius: 3px;

  color-scheme: light;
}

/* Dark palette — opt-in only.
 *
 * The site deliberately does NOT follow prefers-color-scheme. Light is the
 * brand's default and the version the social card and any print material
 * match, so every visitor sees it first regardless of their OS setting. Dark
 * is reachable through the header toggle, and that choice is remembered.
 *
 * This is why there is no `@media (prefers-color-scheme: dark)` here: adding
 * one back would reintroduce dark-by-default for anyone whose system is dark. */
:root[data-theme='dark'] {
  --paper: #0d1512;
  --surface: #121c18;
  --tint: #16211d;
  --ink: #e9e6dc;
  --ink-soft: #98a69e;
  --line: #24322c;
  --accent: #6ccfa2;
  --accent-ink: #08130e;
  --accent-wash: #16302459;
  --warn: #e0b184;
  --warn-wash: #2a2015;
  --error: #e79b95;

  /* Dark equivalents. Text-on-fill measures 8.7:1 (busy) and 8.13:1 (free). */
  --cal-busy-bg: #3b201d;
  --cal-busy-ink: #f2b8b1;
  --cal-busy-line: #54302c;
  --cal-free-bg: #16302a;
  --cal-free-ink: #7fd6ac;
  --cal-free-line: #224238;
  --cal-past-ink: #5c665f;
}

/* Keeps native controls, scrollbars and form widgets in step with an
   explicit choice rather than with the system setting. */
:root[data-theme='light'] {
  color-scheme: light;
}
:root[data-theme='dark'] {
  color-scheme: dark;
}

/* ---------- base ------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Paper grain. Purely atmospheric, sits above everything but catches nothing. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0 0 1.1em;
  text-wrap: pretty;
}
p:last-child {
  margin-bottom: 0;
}

a {
  color: inherit;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-underline-offset: 0.22em;
  text-decoration-thickness: from-font;
}
a:hover {
  text-decoration-color: currentColor;
}

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

:where(a, button, input, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

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

.skip {
  position: absolute;
  left: 50%;
  top: 0;
  translate: -50% -120%;
  z-index: 100;
  padding: 0.7rem 1.2rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.9rem;
  text-decoration: none;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: translate 0.18s ease;
}
.skip:focus {
  translate: -50% 0;
}

/* Unfinished content, so nobody mistakes a placeholder for real copy. */
.todo {
  background: var(--warn-wash);
  color: var(--warn);
  font-family: var(--body);
  /* Capped so a placeholder inside the display-size <h1> stays a small note
     rather than becoming the loudest thing on the page. */
  font-size: min(0.86em, 1rem);
  font-weight: 400;
  letter-spacing: 0;
  font-style: italic;
  vertical-align: middle;
  padding: 0.05em 0.45em;
  border-radius: var(--radius);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ---------- layout ----------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--rhythm);
  border-top: 1px solid var(--line);
}

.section--tint {
  background: var(--tint);
}

/* Editorial two-column: heading sits in its own narrow column and stays put. */
.section__grid {
  display: grid;
  gap: clamp(1rem, 4vw, 3.5rem);
}

@media (min-width: 56rem) {
  .section__grid {
    grid-template-columns: 14rem 1fr;
    align-items: start;
  }
  .section__heading {
    position: sticky;
    top: 6rem;
  }
}

.section__heading {
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
  color: var(--ink);
}
.section__heading::after {
  content: '';
  display: block;
  width: 2.25rem;
  height: 2px;
  margin-top: 0.85rem;
  background: var(--accent);
}

.section__lead {
  font-size: 1.05em;
  color: var(--ink-soft);
  max-width: 46ch;
  margin-bottom: 2rem;
}

.prose {
  max-width: 58ch;
}
.prose p + p {
  margin-top: 0;
}

/* ---------- header ----------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding-block: 0.85rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 0.6rem;
  text-decoration: none;
  flex: none;
}

/* The mortar sits freestanding in the accent green — no container tile, which
   would read as an app icon rather than a mark. */
.wordmark__mark {
  flex: none;
  color: var(--accent);
}

.wordmark__text {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: 0.01em;
}

/* Groups the nav and the theme toggle so the header stays two children wide.
   On a phone the whole group drops to its own row beneath the wordmark, which
   keeps the header to two rows rather than three. */
.site-header__end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1.35rem;
  font-size: 0.94rem;
}

@media (max-width: 47.99rem) {
  .site-header__end {
    flex: 1 1 100%;
    justify-content: flex-start;
  }
  .site-nav {
    gap: 0.4rem 1.1rem;
  }
  /* The toggle sits at the far end of its row rather than crowding the links. */
  .theme-toggle {
    margin-left: auto;
  }
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px; /* comfortable tap target on touch screens */
  text-decoration: none;
  color: var(--ink-soft);
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.site-nav a:hover {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

/* On a phone, five wrapped links turn the sticky header into a fifth of the
   screen. This is a one-page site, so the two narrative links stand down and the
   header keeps only the wordmark and the two destinations that convert. */
@media (max-width: 47.99rem) {
  /* Only "Beschikbaarheid" survives on a phone, alongside the language and
     theme controls. Everything else fits on one row that way, with room for the
     longer French labels — and both hero buttons already reach About and
     Contact, so nothing becomes unreachable.
     Must out-specify `.site-nav a` above, hence the element in the selector. */
  .site-nav a.site-nav__minor {
    display: none;
  }

  /* Wordmark and nav sit on two rows at this width. Pinned, that costs a sixth
     of a phone screen for the whole visit, so the header scrolls away instead —
     the hero carries both calls to action anyway. */
  .site-header {
    position: static;
  }
  html {
    scroll-padding-top: 1rem;
  }
}

.lang-switch {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.09em;
  color: var(--ink) !important;
  padding-inline: 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.lang-switch:hover {
  border-color: var(--accent) !important;
  background: var(--accent-wash);
}

/* The toggle ships hidden and is revealed by app.js, so a reader without
   JavaScript is never shown a control that cannot do anything. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.theme-toggle[hidden] {
  display: none;
}
.theme-toggle:hover {
  color: var(--ink);
  border-color: var(--line);
  background: var(--accent-wash);
}

/* Show the icon for the theme the button switches *to*. */
.theme-toggle__sun {
  display: none;
}
:root[data-theme='dark'] .theme-toggle__sun {
  display: block;
}
:root[data-theme='dark'] .theme-toggle__moon {
  display: none;
}

/* ---------- hero ------------------------------------------------------- */

.hero {
  padding-block: clamp(3.5rem, 11vw, 8rem) var(--rhythm);
}

.hero__inner {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
}

.hero--portrait .hero__inner {
  align-items: center;
}

@media (min-width: 52rem) {
  .hero--portrait .hero__inner {
    grid-template-columns: 1.35fr 1fr;
  }
}

.hero__role {
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 1.1rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--line);
  max-width: 34ch;
}

.hero__name {
  font-size: clamp(2.75rem, 1.4rem + 6.2vw, 5.5rem);
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 0.98;
  font-variation-settings: 'SOFT' 0, 'WONK' 1;
  margin-bottom: 1.5rem;
}

.hero__intro {
  font-size: clamp(1.075rem, 1rem + 0.4vw, 1.3rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 44ch;
  margin-bottom: 2.25rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0;
}

.hero__portrait {
  margin: 0;
}
.hero__portrait img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radius);
  filter: saturate(0.92);
}

/* ---------- buttons ---------------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.72rem 1.4rem;
  font: inherit;
  font-size: 0.96rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.button:hover {
  border-color: var(--accent);
  background: var(--accent-wash);
}

.button--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.button--primary:hover {
  background: color-mix(in srgb, var(--accent) 84%, var(--ink));
  border-color: color-mix(in srgb, var(--accent) 84%, var(--ink));
  color: var(--accent-ink);
}
.button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---------- facts (the spec sheet) ------------------------------------- */

.facts {
  margin: 0;
  border-top: 1px solid var(--line);
}

.facts__row {
  display: grid;
  gap: 0.15rem 2rem;
  padding-block: 1.05rem;
  border-bottom: 1px solid var(--line);
}

@media (min-width: 34rem) {
  .facts__row {
    grid-template-columns: 11rem 1fr;
    align-items: baseline;
  }
}

.facts dt {
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--ink-soft);
}

.facts dd {
  margin: 0;
  max-width: 52ch;
}

/* ---------- faq -------------------------------------------------------- */

/* Native <details>, so the accordion works with no JavaScript and stays
   keyboard-accessible. The answers sit in the HTML whether open or closed,
   which is what lets crawlers and AI models extract them. */
.faq {
  border-top: 1px solid var(--line);
  max-width: 52ch;
}

.faq__item {
  border-bottom: 1px solid var(--line);
}

.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.05rem;
  font-family: var(--display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.35;
  cursor: pointer;
  list-style: none;
}
.faq__q::-webkit-details-marker {
  display: none;
}
.faq__q::after {
  content: '+';
  flex: none;
  font-family: var(--body);
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--accent);
  transition: rotate 0.18s ease;
}
.faq__item[open] .faq__q::after {
  content: '−';
}
.faq__q:hover {
  color: var(--accent);
}
.faq__q:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.faq__a {
  padding-bottom: 1.15rem;
  color: var(--ink-soft);
  max-width: 48ch;
}

/* ---------- calendar --------------------------------------------------- */

.calendar {
  max-width: 34rem;
}

.calendar__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.calendar__month {
  /* Was an <h3>, so it inherited the display face and zero margin from the
     heading rules; as a <p> it has to state both itself. */
  margin: 0;
  font-family: var(--display);
  letter-spacing: -0.015em;
  font-size: 1.15rem;
  font-weight: 600;
  text-align: center;
  flex: 1;
}

.calendar__nav {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.calendar__nav:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.calendar__nav:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.cal {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-variant-numeric: tabular-nums;
}

.cal th {
  padding-bottom: 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.cal__day {
  padding: 2px;
  text-align: center;
}

.cal__num {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  font-size: 0.92rem;
  color: var(--ink-soft);
  border: 1px solid transparent;
  border-radius: var(--radius);
}

/* Red = booked, green = free.
 *
 * Chosen knowingly against the red/green colour-blindness problem: under
 * deuteranopia and protanopia these two fills measure ~1.1:1 against each
 * other, i.e. indistinguishable, and no symbol is shown to compensate. The
 * screen-reader label on booked days is unaffected, so assistive tech still
 * conveys it; sighted colour-blind visitors do not get the distinction.
 *
 * Text contrast within each cell is high (>= 6.4:1) so the numbers stay
 * legible regardless. */
.cal__day--busy .cal__num {
  background: var(--cal-busy-bg);
  color: var(--cal-busy-ink);
  border-color: var(--cal-busy-line);
  font-weight: 600;
}

.cal__day--free .cal__num {
  background: var(--cal-free-bg);
  color: var(--cal-free-ink);
  border-color: var(--cal-free-line);
  font-weight: 600;
}

/* A day already gone is neither bookable nor worth advertising as busy. */
.cal__day--past .cal__num {
  color: var(--cal-past-ink);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.cal__day--empty .cal__num {
  visibility: hidden;
}

.calendar__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.25rem;
  margin-top: 1.15rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.legend__item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.swatch {
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 2px;
  border: 1px solid var(--line);
}
.swatch--busy {
  background: var(--cal-busy-bg);
  border-color: var(--cal-busy-line);
}
.swatch--free {
  background: var(--cal-free-bg);
  border-color: var(--cal-free-line);
}

.calendar__updated {
  margin-left: auto;
  font-size: 0.8rem;
  opacity: 0.75;
}

.calendar__status {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.calendar__fallback {
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  max-width: 42rem;
}
.calendar__fallback p:first-child {
  margin-bottom: 1.1rem;
  color: var(--ink-soft);
}

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

/* With the form gone these two lines ARE the contact section, so they are sized
   to be read and tapped rather than tucked away as a footnote. */
.direct {
  display: grid;
  gap: 0.75rem;
  max-width: 34rem;
}

.direct__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 1rem;
  margin: 0;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line);
}
.direct__row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.direct__label {
  flex: none;
  min-width: 5.5rem;
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
}

.direct__value {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--display);
  font-size: clamp(1.15rem, 1rem + 0.8vw, 1.5rem);
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
}
.direct__value:hover {
  color: var(--accent);
}

/* ---------- footer ----------------------------------------------------- */

.site-footer {
  padding-block: clamp(2.5rem, 6vw, 4rem);
  background: var(--ink);
  color: var(--paper);
}

/* By default the footer is an ink panel; in dark that would be invisible
   against the page, so it becomes a raised surface instead. */
:root[data-theme='dark'] .site-footer {
  background: var(--surface);
  border-top: 1px solid var(--line);
  color: var(--ink);
}

.site-footer__inner {
  display: grid;
  gap: 1.75rem;
}

@media (min-width: 48rem) {
  .site-footer__inner {
    grid-template-columns: 1fr auto;
    align-items: start;
  }
}

.site-footer__brand {
  display: grid;
  gap: 0.35rem;
  margin: 0;
}
.site-footer__brand .wordmark {
  margin: 0;
  min-height: 0;
}
.site-footer__brand .wordmark__text {
  font-size: 1.35rem;
}
/* Accent green is too dark against the footer's ink panel in light mode, so the
   mark borrows the footer's own foreground colour instead. */
.site-footer .wordmark__mark {
  color: inherit;
}

.site-footer__tagline {
  font-size: 0.9rem;
  opacity: 0.7;
}

.site-footer__legal {
  display: grid;
  gap: 0.3rem;
  font-style: normal;
  font-size: 0.85rem;
  opacity: 0.75;
}

.site-footer .todo {
  background: color-mix(in srgb, currentColor 14%, transparent);
  color: inherit;
}

/* ---------- developer credit ------------------------------------------- */

/* Spans both footer columns as the final line. The footer is a dark panel in
   BOTH themes (ink in light mode, raised surface in dark), so these colours are
   measured against both:
       #8a938e  5.23:1 on light-mode footer, 5.51:1 on dark  -> AA
       #6ccfa2  8.72:1 on light-mode footer, 9.20:1 on dark  -> AA
   The light-mode accent (#1b6b4e) is deliberately NOT used here: it measures
   2.56:1 against the footer panel and would fail outright on hover. */
.site-credit {
  grid-column: 1 / -1;
  margin: 0;
  padding-top: 1.5rem;
  border-top: 1px solid color-mix(in srgb, currentColor 15%, transparent);
  text-align: center;
  font-size: 11px;
  line-height: 1.5;
  color: #8a938e;
}

.site-credit__link {
  /* Small text, but a full-size hit area. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  /* Deliberately indistinguishable at rest: same colour as the line it sits in,
     no underline. That is a WCAG 1.4.1 miss, accepted here because this is the
     developer's own credit rather than functionality any visitor needs to find.
     Hover and focus both restore the accent colour and the underline. */
  color: inherit;
  text-transform: none;
  text-decoration: none;
  transition: color 0.15s ease;
}
.site-credit__link:hover,
.site-credit__link:focus-visible {
  color: #6ccfa2;
  text-decoration: underline;
  text-decoration-color: currentColor;
}
.site-credit__link:focus-visible {
  outline: 2px solid #6ccfa2;
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------- motion ----------------------------------------------------- */

/* One orchestrated entrance on the hero, then the page leaves you alone. */
@media (prefers-reduced-motion: no-preference) {
  .hero__role,
  .hero__name,
  .hero__intro,
  .hero__actions,
  .hero__portrait {
    animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
  }
  .hero__role {
    animation-delay: 0.04s;
  }
  .hero__name {
    animation-delay: 0.1s;
  }
  .hero__intro {
    animation-delay: 0.2s;
  }
  .hero__actions {
    animation-delay: 0.28s;
  }
  .hero__portrait {
    animation-delay: 0.16s;
  }
}

/* Deliberately translate-only, no opacity.
 *
 * Fading in from opacity 0 meant the hero text was invisible at first paint,
 * and Largest Contentful Paint ignores invisible elements — so LCP was not
 * recorded until the animation finished, measuring ~1.0s on a page that had
 * otherwise finished loading in 50ms. Moving without fading keeps the entrance
 * while letting the text count as painted immediately. */
@keyframes rise {
  from {
    translate: 0 0.9rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
