/* ==========================================================================
   AGEDEC. Single shared stylesheet. Linked from every page.
   Zero style="" attributes in any HTML file. Anything reused lives here.
   ========================================================================== */

:root {
  /* Grounds */
  --paper:       #F2F5EC;  /* page ground, a paper with a green cast, from the brochure */
  --sage:        #E2ECD7;  /* alternate section band */
  --green-deep:  #1F4A2C;  /* inverted band */
  --navy:        #16324B;  /* from the logo wordmark */

  /* Text on light grounds */
  --ink:         #14263A;  /* body text.       13.92 on paper, 12.58 on sage */
  --heading:     var(--navy);  /* headings.    11.96 on paper. Same literal as --navy, tied so they cannot drift. */
  --muted:       #586152;  /* secondary text.   5.87 on paper,  5.30 on sage */
  --green:       #2E6B3F;  /* links, accents.   5.79 on paper,  5.23 on sage */
  --green-hover: #24552F;  /* .btn-solid:hover.  7.89, paper text on it */

  /* Text on the inverted band */
  --on-deep:          #FFFFFF;  /* 10.12 on green-deep */
  --on-deep-muted:    #CFE0C4;  /*  7.29 on green-deep */
  --gold-on-deep:     #D8BE7A;  /*  5.58 on green-deep, 7.27 on navy */

  /* Decorative only */
  --gold:        #C8A24A;  /* 2.18 on paper. NEVER used for text on a light ground.
                              Rules, underlines, small marks only. For gold text on a
                              dark ground use --gold-on-deep instead. */
  --line:        #D6DCCB;  /* hairlines */

  /* Type */
  --font-display: 'Archivo', system-ui, sans-serif;
  --font-body:    'Source Serif 4', Georgia, serif;

  /* Rhythm */
  --measure: 68ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-y: clamp(3rem, 5.5vw, 5rem);
  --nav-h: 78px;
  --btn-radius: 6px;
}

/* ==========================================================================
   Class contract. index.html uses these exact names.

   .js                    added to <html> by the inline script in <head>,
                           before the stylesheet link. Gates .reveal.
   .at-top                added to <html> by site.js when window.scrollY < 8
                           AND the page has a .hero, removed otherwise. Makes
                           .site-header transparent. Fails safe two ways:
                           absent by default (a dead script leaves the header
                           solid), and gated on .hero (a Phase 2 page with no
                           full-bleed hero never gets it, even if the script
                           runs fine, so it never shows white nav text on a
                           paper-ground top).

   .wrap                  max-width content wrapper, padded by --gutter
   .section               vertical section padding
   .section--sage         section modifier, sage ground
   .section--deep         section modifier, inverted ground
   .skip-link             skip to #main, first focusable element
   .label                 label-scale text (Archivo 600, 0.78rem)
   .muted                 secondary text colour
   .lead                  lead paragraph, used in the hero and in section
                           intros, with a .hero .lead override for the
                           light-on-photo variant

   .site-header           header row: brand, nav, lang
   .brand                 logo image plus wordmark, a link
   .brand__name           "AGEDEC" wordmark
   .brand__tagline        full name beneath the wordmark
   .nav                   the nav link list
   .nav__toggle           mobile nav toggle button, shown below 780px,
                           last child of .site-header .wrap. Icon only,
                           labelled via data-fr-aria / data-en-aria.
   .nav__toggle span      one of the three hamburger bars
   .lang                  language switch, holds the FR / EN / KR buttons

   .btn                   button base
   .btn-solid             solid fill button
   .btn-outline           outline button
   .on-deep               modifier on .btn-solid or .btn-outline, inside .section--deep
   .btn-row               wraps a row of buttons, e.g. the two hero buttons

   .hero                  full viewport photo hero, text pinned bottom left,
                           runs under the header
   .hero__body            hero text block, bottom left over the photo
   .hero__media           absolute-positioned photo layer, fills .hero
   .hero__caption         location line, last child of .hero, bottom right

   .record                one program record: photo, paragraph, dl
   .record--alt           modifier, swaps photo and text sides at 900px+
   .record__media         the photo wrapper
   .record__body          the text and dl wrapper
   .record__years         years line beneath the record h3

   .timeline              the "Since 1987" list, a real <ol>
   .timeline__year        the year, first in each row

   .place-list            wrapper grid for the three .place blocks
   .place                 one location marker (heading plus one line)

   .stats                 stats banner grid, four .stat children
   .stat                  one stat: a .stat__label and a .stat__value.
                           DOM order is dt (.stat__label) then dd
                           (.stat__value), as the dl content model
                           requires; .stat uses flex column-reverse to
                           paint the value above the label without
                           putting dd before dt in the source
   .stat__value           the figure, e.g. "1987"
   .stat__label           the label under the figure

   .areas                 areas-of-work grid, four .area children
   .area                  one area of work: a photo, an h3 and a paragraph

   .footer-grid           the footer's three-column wrapper
   .site-footer__bottom-bar   copyright and credit row

   .reveal                hero entrance element, hidden until .js adds .is-visible
   .reveal--delay         modifier, ~120ms stagger for the second element
   .is-visible            added to .reveal elements by site.js after load
   ========================================================================== */

/* ==========================================================================
   Reset
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(1.02rem, 1.05vw, 1.14rem);
  line-height: 1.65;
}

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

a {
  color: var(--green);
  transition: color 0.2s ease, opacity 0.2s ease;
}

a:not(.btn):not(.brand) {
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.section--deep a {
  color: var(--gold-on-deep);  /* 5.58 on green-deep. Base --green is 1.59:1 here, invisible. */
}

/* ==========================================================================
   Typography
   ========================================================================== */

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--heading);
  margin: 0;
}

h1 {
  font-size: clamp(2.5rem, 5vw, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.025em;
  max-width: 14ch;
}

h2 {
  font-size: clamp(1.75rem, 3.2vw, 2.6rem);
  line-height: 1.15;
}

h3 {
  font-size: 1.25rem;
  line-height: 1.25;
}

/* Body copy is capped at --measure inside content areas. */
main p {
  max-width: var(--measure);
}

.lead {
  font-size: clamp(1.15rem, 1.6vw, 1.35rem);
  line-height: 1.55;
  max-width: 46ch;
  margin-top: 1.75rem;
}

.label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}

.muted {
  color: var(--muted);
}

.section--deep .muted {
  color: var(--on-deep-muted);
}

/* ==========================================================================
   Layout
   ========================================================================== */

.wrap {
  max-width: 1140px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-y);
}

section {
  scroll-margin-top: calc(var(--nav-h) + 16px);
}

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

.section--deep {
  background: var(--green-deep);
  color: var(--on-deep);
}

.section--deep h1,
.section--deep h2,
.section--deep h3 {
  color: var(--on-deep);
}

/* ==========================================================================
   Skip link
   ========================================================================== */

.skip-link {
  position: absolute;
  left: 0;
  top: -100%;
  z-index: 100;
  background: var(--green-deep);
  color: var(--on-deep);
  font-family: var(--font-display);
  font-weight: 600;
  padding: 0.75rem 1.25rem;
}

.skip-link:focus {
  top: 0;
}

/* ==========================================================================
   Header, brand, nav, language switch
   ========================================================================== */

.site-header {
  position: sticky;  /* sticky still establishes a containing block, same as relative did */
  top: 0;
  z-index: 50;
  height: var(--nav-h);
  padding-block: 0;
  background: rgba(242, 245, 236, 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.site-header .wrap {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gutter);
}

.site-header,
.site-header .brand__name,
.site-header .nav a {
  transition: background-color 0.25s ease, color 0.25s ease,
              border-color 0.25s ease;
}

.at-top .site-header {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
}

.at-top .site-header::before {
  /* The hero's own gradient is only 20% opaque at its top stop, so over
     a bright sky the header's white text can drop to ~1.5:1. This scrim
     is measured against that same bright case: stacked on the hero's
     0.20, 0.62 gives white text 6.18:1. Do not reduce it.
     .site-header already establishes a stacking context (sticky +
     z-index: 50), so z-index: -1 here is scoped inside it and cannot
     drop behind the hero photo, only behind .site-header's own content. */
  content: '';
  position: absolute;
  inset: 0;
  bottom: -40px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(15, 32, 22, 0.62) 0%,
    rgba(15, 32, 22, 0.45) 60%,
    rgba(15, 32, 22, 0)   100%
  );
}

.at-top .site-header .brand__name,
.at-top .site-header .brand__tagline,
.at-top .site-header .nav a,
.at-top .site-header .lang button {
  color: var(--on-deep);
}

.at-top .site-header .nav__toggle span {
  background: var(--on-deep);
}

.at-top .site-header .nav a[aria-current="page"] {
  color: var(--on-deep);
}

.at-top .site-header .lang button {
  border-color: rgba(255, 255, 255, 0.45);
}

.at-top .site-header .lang button[aria-pressed="true"] {
  background: var(--on-deep);
  border-color: var(--on-deep);
  color: var(--green-deep);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
}

.brand img {
  width: 40px;
  height: 40px;
}

.brand__name {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--heading);
  line-height: 1.2;
}

.brand__tagline {
  display: block;
  color: var(--muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}

.nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.nav a {
  position: relative;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--heading);
  text-decoration: none;
}

@media (hover: hover) {
  .nav a:hover {
    color: var(--green);
  }
}

.nav a[aria-current="page"] {
  color: var(--green);
  text-decoration: underline;
  text-decoration-color: var(--gold);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

.nav a[aria-disabled="true"] {
  cursor: default;
}

.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
}

.nav__toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--heading);
  transition: transform 0.25s ease, opacity 0.2s ease;
}

.nav__toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav__toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

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

@media (max-width: 779px) {
  .site-header {
    /* backdrop-filter establishes a containing block for position:fixed
       descendants. .nav is fixed at this width, so left on, it traps the
       open panel inside the 78px header box instead of the viewport.
       Disabled here because of that trap, not as a taste choice, and the
       background goes fully opaque to compensate: without the blur,
       the rgba ground alone would let scrolled text smear through. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--paper);
  }

  .brand__tagline {
    display: none;
  }

  .nav__toggle {
    display: flex;
  }

  .nav {
    position: fixed;
    top: var(--nav-h);
    left: 0;
    right: 0;
    bottom: 0;
    flex-direction: column;
    align-items: flex-start;
    background: var(--paper);      /* opaque, not the header's rgba */
    overflow-y: auto;
    padding: 2rem var(--gutter);
    gap: 1.25rem;
  }

  .nav[hidden] {
    display: none;
  }

  .nav a {
    padding-block: 0.5rem;
  }
}

.lang {
  display: flex;
  gap: 0.5rem;
}

.lang button {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--btn-radius);
  padding: 0.3rem 0.6rem;
  color: var(--heading);
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.lang button[aria-pressed="true"] {
  background: var(--green);
  border-color: var(--green);
  color: var(--paper);
}

@media (hover: hover) {
  .lang button:hover {
    border-color: var(--green);
  }
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  border-radius: var(--btn-radius);
  padding: 1.05rem 1.9rem;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease,
              border-color 0.2s ease, transform 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  a,
  .lang button,
  .site-header,
  .site-header .brand__name,
  .site-header .nav a,
  .nav__toggle span {
    transition-duration: 0s;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .btn:active {
    transform: translateY(1px);
  }
}

.btn-solid {
  background: var(--green);       /* paper text on green: 5.79 */
  color: var(--paper);
  border-color: var(--green);
}

.btn-outline {
  background: transparent;
  color: var(--green);
  border-color: var(--green);
}

.btn-solid.on-deep {
  background: var(--on-deep);
  color: var(--green-deep);
  border-color: var(--on-deep);
}

.btn-outline.on-deep {
  background: transparent;
  color: var(--on-deep);
  border-color: var(--on-deep);
}

@media (hover: hover) {
  .btn-solid:hover  { background: var(--green-hover); border-color: var(--green-hover); }
  .btn-outline:hover { background: var(--green); color: var(--paper); }
  .btn-solid.on-deep:hover  { background: var(--sage); border-color: var(--sage); }
  .btn-outline.on-deep:hover { background: var(--on-deep); color: var(--green-deep); }
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 2rem;
}

.hero .btn {
  padding: 1.15rem 2.1rem;
  font-size: 1.05rem;
}

.hero .btn-solid {
  background: var(--green);      /* white text on green: 6.38 */
  color: #FFFFFF;
  border-color: var(--green);
}

.hero .btn-outline {
  background: rgba(255, 255, 255, 0.10);
  color: #FFFFFF;
  border-color: rgba(255, 255, 255, 0.75);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

@media (hover: hover) {
  .hero .btn-solid:hover  { background: var(--green-hover); border-color: var(--green-hover); }
  .hero .btn-outline:hover { background: rgba(255, 255, 255, 0.20); border-color: #FFFFFF; }
}

/* ==========================================================================
   Hero. Two columns above 900px, stacked below.
   ========================================================================== */

.hero {
  position: relative;
  display: grid;
  align-content: end;
  min-height: 100vh;
  min-height: 100svh;
  margin-top: calc(-1 * var(--nav-h));
  padding: var(--nav-h) 0 0 0;
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: auto;
}

.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Measured, not estimated. A 45% scrim over the photo's brightest area
     (top right sky) gives white text 2.85:1, which fails AA. This ramp
     gives 6.28:1 worst case where the text actually sits, below the 55%
     stop. Do not lighten these stops. */
  background: linear-gradient(
    180deg,
    rgba(15, 32, 22, 0.20)   0%,
    rgba(15, 32, 22, 0.35)  30%,
    rgba(15, 32, 22, 0.70)  55%,
    rgba(15, 32, 22, 0.90) 100%
  );
}

.hero__body {
  position: relative;
  z-index: 1;
  align-self: end;
  padding-inline: max(var(--gutter), calc((100vw - 1140px) / 2));
  padding-bottom: clamp(3.5rem, 9vh, 7rem);
  padding-top: 0;
}

.hero h1 {
  color: var(--on-deep);
  max-width: 16ch;
}

.hero .lead {
  color: var(--on-deep);
  max-width: 52ch;
}

.hero :focus-visible {
  outline-color: var(--gold-on-deep);
}

.hero__caption {
  position: absolute;
  right: max(var(--gutter), calc((100vw - 1140px) / 2));
  bottom: 1.5rem;
  z-index: 1;
  background: none;
  padding: 0;
  color: var(--on-deep-muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

@media (max-width: 779px) {
  .hero__caption {
    position: static;
    margin: 0 var(--gutter) 1.5rem;
  }
}

/* ==========================================================================
   Record. A titled block with a photo, a paragraph and a labelled data
   list. Not a card: no box, no shadow, no border radius.
   Unused on index.html as of the Phase 1c restructure. Reserved for
   programmes.html in Phase 2.
   ========================================================================== */

.record {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  padding-top: clamp(2.5rem, 5vw, 4rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--line);
  border-left: none;
  padding-left: 0;
}

.record:first-of-type {
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}

.record__body {
  /* Absorbs the h3's -1rem pull below. Without this, the gold marker's
     margin has nothing to cancel against, and at 375px, where
     .record__body is full width sitting right at the --gutter floor,
     the pull lands the marker 4px from the viewport edge instead of
     flush with the text column. */
  padding-left: 1rem;
}

.record__body h3 {
  border-left: 3px solid var(--gold);
  padding-left: 1rem;
  margin-left: -1rem;
}

@media (min-width: 900px) {
  .record {
    grid-template-columns: 5fr 7fr;
    align-items: start;
  }

  .record--alt {
    grid-template-columns: 7fr 5fr;
  }

  .record--alt .record__body {
    grid-column: 1;
  }

  .record--alt .record__media {
    grid-column: 2;
  }
}

.record__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.record__years {
  display: block;
  color: var(--muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  margin-top: 0.25rem;
}

.record__body dl {
  margin: 1.5rem 0 0;
  border-top: 1px solid var(--line);
  padding-top: 1.25rem;
}

.record__body dt {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--muted);
  margin-top: 1rem;
}

.record__body dt:first-child {
  margin-top: 0;
}

.record__body dd {
  margin: 0.25rem 0 0;
}

@media (min-width: 700px) {
  .record__body dl {
    display: grid;
    grid-template-columns: 10.5rem 1fr;
    column-gap: var(--gutter);
    row-gap: 0.9rem;
    align-items: baseline;
  }

  .record__body dt {
    margin-top: 0;
  }

  .record__body dd {
    margin-top: 0;
  }
}

/* ==========================================================================
   Timeline. A genuine sequence: year, then text, no markers beyond the year.
   Unused on index.html as of the Phase 1c restructure. Reserved for
   association.html in Phase 2.
   ========================================================================== */

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.timeline li {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
  padding-block: 1.5rem;
  align-items: baseline;
  border-top: 1px solid var(--line);
}

.timeline li:first-child {
  border-top: none;
}

@media (min-width: 600px) {
  .timeline li {
    grid-template-columns: 6rem 1fr;
    column-gap: 2rem;
  }
}

.timeline__year {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  color: var(--green);
}

/* main p { max-width: var(--measure) } (68ch) was applying inside this
   grid cell too, confirmed by measuring the rendered paragraph width
   against its actual column width before this override. 60ch here is a
   deliberate, timeline-specific cap, not just a removal of the global one. */
.timeline li p,
.timeline li > *:last-child {
  max-width: 60ch;
  margin: 0;
}

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

/* ==========================================================================
   Place. Three location markers, no icons, no boxes.
   Unused on index.html as of the Phase 1c restructure. Reserved for
   association.html in Phase 2.
   ========================================================================== */

.place-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  margin-top: 2rem;
}

@media (min-width: 780px) {
  .place-list {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--gutter);
    align-items: stretch;
  }
}

.place {
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.place h3 {
  margin-bottom: 0.85rem;
}

@media (min-width: 780px) {
  .place {
    padding-block: 0.25rem;
    border-top: none;
    padding-left: var(--gutter);
    border-left: 1px solid var(--line);
  }

  .place:first-child {
    padding-left: 0;
    border-left: none;
  }
}

/* ==========================================================================
   Stats banner
   ========================================================================== */

.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2.5rem var(--gutter);
  margin: 2.5rem 0 0;
}

@media (min-width: 780px) {
  .stats { grid-template-columns: repeat(4, 1fr); }
}

.stat {
  margin: 0;
  display: flex;
  flex-direction: column-reverse; /* DOM is dt then dd, valid per the dl content
                                      model; this repaints the dd (value) above
                                      the dt (label) without touching source order */
  justify-content: flex-end; /* main-axis end, which in column-reverse is the
                                 top, so all four values share one baseline
                                 instead of a two-line label pushing its value up */
  padding: 1.5rem 1.25rem;
  background: rgba(255, 255, 255, 0.05); /* measured ceiling on green-deep: 0.05
                                             resolves to #2A5337, where gold-on-deep
                                             is 4.84 and on-deep-muted is 6.32.
                                             At 0.10 gold drops to 4.19 and fails AA.
                                             Do not raise this. */
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--btn-radius);
}

.stat__value {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.4rem, 4.5vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gold-on-deep);   /* 5.58 on green-deep */
}

.stat__label {
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--on-deep-muted);  /* 7.29 on green-deep */
  max-width: 20ch;
}

/* ==========================================================================
   Areas of work
   ========================================================================== */

.areas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  margin: 2.5rem 0 0;
}

@media (min-width: 620px) {
  .areas { grid-template-columns: repeat(2, 1fr); gap: var(--gutter); }
}

@media (min-width: 1000px) {
  .areas { grid-template-columns: repeat(4, 1fr); }
}

.area { margin: 0; }

.area img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.area h3 {
  margin-top: 0.9rem;
  font-size: 1.1rem;
}

.area p { margin-top: 0.6rem; max-width: none; font-size: 0.98rem; }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  background: var(--paper);
  border-top: none;
  padding-block: var(--section-y);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
}

@media (min-width: 780px) {
  .footer-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.site-footer img {
  width: 64px;
  height: 64px;
}

@media (hover: hover) {
  .site-footer a:hover {
    opacity: 0.7;
  }
}

.site-footer__bottom-bar {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ==========================================================================
   Focus, motion, and the no-JavaScript fallback
   ========================================================================== */

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

.section--deep :focus-visible,
.on-deep:focus-visible {
  outline-color: var(--gold-on-deep);
}

/* .reveal is gated on .js, set by an inline script at the top of <head>
   in index.html, not on <noscript>, because a script that 404s or throws
   never fires <noscript> either and would otherwise leave the page blank
   for everyone without prefers-reduced-motion set. site.js adds
   .is-visible after load; .reveal--delay staggers the second element. */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.6s ease-out, transform 0.6s ease-out;
  }

  .js .reveal.is-visible {
    opacity: 1;
    transform: none;
  }

  .reveal--delay {
    transition-delay: 0.12s;
  }
}
