/* ==========================================================================
   Lessons from Life: Part II — The Letters
   Explorer Publishing · single-page site stylesheet
   Replaces the Canvas theme bundle (bootstrap/style/dark/font-icons/
   animate/responsive/swiper + jquery/plugins/functions ≈ 1.4 MB).
   ========================================================================== */

/* ---------- Lateef, self-hosted ----------------------------------------
   Served from this origin instead of fonts.googleapis.com. The Google link was
   a render-blocking stylesheet on a third-party origin, costing a DNS lookup,
   a TLS handshake and a round trip before any Arabic could paint. Only the
   Arabic subset is shipped - the English column is Georgia, so Google's latin
   and latin-ext faces were dead weight (6 files down to 2).
   ---------------------------------------------------------------------- */
@font-face {
  font-family: 'Lateef';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/lateef-arabic-400.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: 'Lateef';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/lateef-arabic-700.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;
}

/* ---------- Design tokens (from the Part 2 EDM) ---------- */
:root {
  --navy:        #1E3E69;
  --navy-deep:   #16304F;
  --navy-soft:   #344A72;
  --gold:        #A08F69;
  --gold-light:  #A89875;
  --yellow:      #FFF205;
  --paper:       #FFFFFF;
  --grey:        #EDEDED;
  --rule:        rgba(160,143,105,.45);

  --serif:  Georgia, "Droid Serif", "Times New Roman", Times, serif;
  --arabic: "Lateef", "Sakkal Majalla", "Traditional Arabic", "Geeza Pro", Tahoma, serif;

  /* Shown behind the hero until the sky image loads. */
  --grad-hero: radial-gradient(120% 90% at 50% 0%, #2A5286 0%, #1E3E69 45%, #12283F 100%);

  --shell:  1180px;
  --gutter: clamp(20px, 5vw, 52px);
  /* Vertical rhythm between sections. Two adjacent sections each contribute
     this, so the space between their content is double the value. */
  --flow:   clamp(48px, 6vw, 84px);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--navy);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg { display: block; max-width: 100%; height: auto; border: 0; }
/* Must outrank the display:grid/flex set on components, or [hidden] is a
   no-op and a collapsed section still occupies its full height. */
[hidden] { display: none !important; }
a { color: var(--gold); }
p { margin: 0 0 1.15em; }
h1, h2, h3 { margin: 0; font-weight: 700; line-height: 1.2; }

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

/* ---------- Helpers ---------- */
.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--navy); color: #fff; padding: 12px 20px;
  border-radius: 6px; text-decoration: none; font-size: 15px;
  transition: top .18s ease;
}
.skip-link:focus { top: 12px; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

/* Arabic type */
/* ---------- Arabic type ------------------------------------------------
   Lateef is a Naskh face and sets much smaller than Georgia at the same px.
   Every Arabic role is scaled here in one place rather than per element -
   doing it piecemeal previously left headings and list items at the English
   size, where they read visibly small next to the Latin column.
   --ar-scale drives the inherited cases; roles that set their own size are
   listed explicitly below so none can be missed again.
   ---------------------------------------------------------------------- */
:root { --ar-scale: 1.42; }

[lang="ar"] {
  font-family: var(--arabic);
  /* 1.85 was set when Arabic ran near the English size; it compounded with the
     1.35x larger type and left Arabic line boxes 59% taller than the English
     column. Lateef declares generous metrics - 145 units per 100px (95 ascent
     + 50 descent) - which is why its natural leading is 1.45. The ink is far
     smaller: 107 units worst case, measured on a string with stacked marks and
     descenders. So 1.35 overlaps the metric boxes but leaves the glyphs 28
     units of clearance, and brings the two columns into the same rhythm. */
  line-height: 1.35;
  font-size: calc(1em * var(--ar-scale));   /* catches bullets and loose text */
}

/* ---------- Site logo ---------- */
.site-logo { position: absolute; top: clamp(20px, 3vw, 40px); left: clamp(20px, 3vw, 40px); z-index: 20; }
.site-logo img { width: clamp(120px, 14vw, 180px); }

/* ---------- Shared section scaffolding ---------- */
.band { position: relative; background: var(--navy) center center / cover no-repeat; }
.band--figure {
  min-height: clamp(420px, 78vh, 820px);
  display: grid; place-items: center;
}
.band--dark { color: #fff; }
.band--dark h2 { color: #fff; }

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

.eyebrow {
  font-size: 13px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 14px;
}
.section-title { font-size: clamp(28px, 4vw, 44px); letter-spacing: .01em; }
.rule { border: 0; border-top: 2px dotted var(--gold); margin-block: clamp(36px, 6vw, 56px); }

/* ---------- Hero -----------------------------------------------------------
   The title and figure are trimmed to their exact alpha bounding boxes, which
   lets them be placed independently per breakpoint.

   Wide screens: a stage carrying the artwork's original 2000x1306 aspect is
   sized to cover the hero, and the two pieces sit at the exact percentage
   offsets they occupied in the designer's composition, so it is reproduced
   pixel-faithfully.

   Portrait screens: the stage becomes a column - title top, figure bottom -
   and the sky crops freely behind. The original lockup is a 1.53:1 landscape
   with the title hard left and the figure hard right; holding that on a phone
   either clips both or shrinks them to a third of the screen.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  background: var(--navy-deep);
  isolation: isolate;
}
.hero__layers { position: absolute; inset: 0; z-index: 0; }

/* --- sky: abstract, crops freely, and the only layer that drifts --- */
.hero__sky {
  position: absolute;
  inset: -12% 0;
  background-image: image-set(url("../images/part2/sky.webp") type("image/webp"),
                              url("../images/part2/sky.jpg")  type("image/jpeg"));
  /* Oversized rather than `cover` so there is vertical slack to crop with.
     At plain cover the image exactly fills the layer, background-position has
     no effect, and the white title lands on the palest band of the gradient.
     Anchoring to the bottom drops the lightest 18% out of frame. */
  background-size: auto 118%;
  background-position: center bottom;
  background-repeat: no-repeat;
  will-change: transform;
}

/* --- stage: covers the hero while holding the artwork's aspect --- */
/* Anchored to the TOP, not centred. The figure's head sits at the very top of
   its trimmed frame, so any upward overflow clips it - which is what happened
   on wide screens: at 2560x1080 the stage is 1672 tall against a 1080 viewport
   and centring pushed the head ~187px above the fold. Anchoring top keeps the
   head safe and lets the overflow fall off the bottom of the robe instead.
   min-width guarantees the stage is always at least as tall as the viewport. */
.hero__stage {
  position: absolute;
  left: 50%; top: 0;
  translate: -50% 0;
  width: 100%;
  min-width: calc(100svh * 2000 / 1306);
  aspect-ratio: 2000 / 1306;
}

.hero__art { position: absolute; display: block; }
.hero__art img { display: block; width: 100%; height: auto; }

/* The figure keeps the offsets it had in the designer's 2000x1306 frame -
   bbox (964,85)-(1904,1306) - since that artwork is unchanged.

   The title was re-cut as a stacked lockup: aspect 1.226 where it used to be
   2.106, so the old width would now have run it 50% down the stage. It is set
   narrower and vertically centred in the space left of the figure instead.
   Right edge lands at 39%, clear of the figure's 48.2%. */
.hero__art--title  { left:  6.000%; top: 29.400%; width: 33.000%; }
.hero__art--figure { left: 48.200%; top:  6.508%; width: 47.000%; }

.hero::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: var(--grad-hero);
}

.scroll-cue {
  position: absolute; bottom: 34px; left: 50%; translate: -50% 0; z-index: 2;
  width: 44px; height: 44px; display: grid; place-items: center;
  color: #fff; text-decoration: none; opacity: .85;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.45));
  animation: cue 2.4s ease-in-out infinite;
}
.scroll-cue:hover { opacity: 1; }
@keyframes cue { 0%,100% { transform: translateY(0); } 50% { transform: translateY(9px); } }

/* --- Portrait / narrow: stack the pieces --------------------------------- */
@media (max-aspect-ratio: 13/10) {
  /* The sky is a vertical gradient, light at top (lum 167) to dark at bottom
     (lum 66). At `cover` on a tall screen the full gradient shows, dropping
     the white title onto the lightest band at 2.5:1 - under the 3:1 large-text
     floor. Oversizing to 175% and anchoring to the bottom crops the pale top
     away, putting the title over lum ~126 (about 4.2:1, better than desktop's
     3.6:1) and keeping the dark base behind the figure. */
  .hero__sky {
    inset: 0;
    background-size: auto 175%;
    background-position: center bottom;
  }

  .hero__stage {
    position: absolute;
    inset: 0;
    left: 0; top: 0;
    translate: none;
    width: 100%;
    min-width: 0;
    height: 100%;
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: clamp(56px, 12svh, 130px) 6vw 0;
  }

  .hero__art { position: static; }

  /* Cap scales with the screen: ~231px on a phone, ~460px on a tablet, so
     the title does not look stranded on the wider portrait viewports. */
  .hero__art--title {
    width: min(70%, 460px);
    flex: 0 0 auto;
  }

  /* Fills the space under the title rather than sitting small at the bottom.
     flex:1 lets it take whatever the title leaves, and the height cap rises to
     72svh; object-position keeps it bottom-anchored as it grows. */
  /* Bleeds past the stage's 6vw side padding: the figure was width-limited to
     330px of a 375px screen, so `contain` letterboxed it and the extra height
     went unused. Cancelling the padding lets it use the full width. */
  .hero__art--figure {
    align-self: stretch;
    margin-inline: -6vw;
    width: auto;
    height: auto;
    min-height: 0;
    flex: 1 1 auto;
    margin-top: clamp(12px, 3svh, 32px);
    display: grid;
    place-items: end center;
  }
  .hero__art--figure img {
    width: auto;
    height: 100%;
    max-height: min(72svh, 720px);
    object-fit: contain;
    object-position: bottom center;
  }

  /* The figure now occupies the bottom edge, where the cue used to sit. */
  .scroll-cue { display: none; }
}

/* ---------- Bilingual two-column body ---------- */
.bilingual {
  display: grid; gap: clamp(38px, 6vw, 76px);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) { .bilingual { grid-template-columns: 1fr 1fr; } }

/* The columns are two independent blocks, so the Arabic heading - 60px against
   the English 44px - made its column taller and pushed the Arabic body out of
   step with the English. Subgrid puts both columns on the same five rows
   (eyebrow / title / body / key-points label / list), so each pair starts
   together regardless of how the two scripts size. Bottom-aligning the eyebrow
   and title rows sits the two titles on a common line rather than a common
   top, which is what the differing cap heights need. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 900px) {
    .bilingual {
      grid-template-rows: repeat(5, auto);
      /* `gap` was authored as the space BETWEEN the two columns. Subgrid makes
         it apply between the five rows as well, adding 4 x 76px down the
         section. Vertical rhythm comes from the elements' own margins, so the
         row gap is zeroed and only the column gap is kept. */
      row-gap: 0;
      column-gap: clamp(38px, 6vw, 76px);
    }
    .col-en, .col-ar {
      display: grid;
      grid-template-rows: subgrid;
      grid-row: span 5;
    }
    .col-en > .eyebrow, .col-ar > .eyebrow,
    .col-en > .section-title, .col-ar > .section-title { align-self: end; }
  }
}

.col-en { text-align: left; }
.col-ar { text-align: right; direction: rtl; }
/* Scoped to the body wrapper, not every <p> in the column. `.col-en p`
   (0,1,1) outranked `.eyebrow` (0,1,0), so the eyebrow that is a <p> took the
   body size while the one that is an <h3> kept 13px - the two labels rendered
   at 17px and 13px in the same column. Targeting the wrapper removes the
   collision instead of escalating specificity against it. */
.col-en > div p { font-size: clamp(15px, 1.15vw, 17px); }
.col-ar > div p { font-size: clamp(21px, 1.62vw, 24px); }

/* Roles that declare their own size need it restated at Arabic scale. */
.col-ar .eyebrow       { font-size: 18px; letter-spacing: .08em; }
.col-ar .section-title { font-size: clamp(38px, 5.5vw, 60px); }

/* ---------- Key points ---------- */
.points { list-style: none; margin: 0; padding: 0; }
.points li { position: relative; padding-left: 26px; margin-bottom: 14px; }
.points li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--gold);
}
.col-ar .points li { padding-left: 0; padding-right: 26px; }
.col-ar .points li::before { left: auto; right: 4px; }

/* ---------- The book (books | title) ------------------------------------
   The supplied plate is navy type on transparent, drawn for a white ground.
   It was split at its natural 125px gutter (x 1031-1155 of 2000) into two
   trimmed halves, so they sit in real columns and reflow instead of being one
   image that has to crop.
   ------------------------------------------------------------------------ */
.book-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  justify-items: center;
  gap: clamp(28px, 4vw, 72px);
  background: #fff;
  padding: clamp(72px, 10vw, 150px) var(--gutter);
  min-height: clamp(560px, 78svh, 940px);
}

.book-split__col { display: grid; place-items: center; width: 100%; }
/* <picture> is inline and shrink-wraps, so centring the column centred the
   WRAPPER, not the image inside it. That only showed on the title, because the
   books image happens to fill its whole track. Making the wrapper a full-width
   block and centring the image within it fixes both. */
.book-split__col picture { display: block; width: 100%; }
/* Drift is applied inline by the parallax handler; will-change keeps it on its
   own layer so the two columns do not repaint the white ground each frame. */
.book-split__col[data-drift] { will-change: transform; }
.book-split__col img { width: 100%; height: auto; margin-inline: auto; }

/* Fluid, so the pair fills a wide viewport instead of floating small in it.
   Ceilings are the assets' native pixel widths - books 783, title 578 - past
   which they would simply be upscaled. The source plate is 2000x1306, so that
   is the hard limit; a larger export is needed to go bigger crisply, and on a
   2x screen these are already being resampled. */
.book-split__col--books img { max-width: min(100%, clamp(420px, 46vw, 780px)); }
/* Capped so the two columns finish at a similar height: the books run
   783x605, and the re-cut title is 578x767, which at its full width would
   tower over them. 450px wide lands it at ~597px tall. */
.book-split__col--title img { max-width: min(100%, clamp(240px, 24vw, 450px)); }

/* Books on top, title beneath. */
@media (max-width: 899.98px) {
  .book-split {
    grid-template-columns: 1fr;
    gap: clamp(30px, 7vw, 52px);
    padding-block: clamp(48px, 11vw, 84px);
  }
  .book-split__col--books img { max-width: min(84%, 420px); }
  .book-split__col--title img { max-width: min(72%, 340px); }
}

/* ---------- Quote (photo | text) ---------------------------------------- */
.quote-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--navy);
  color: #fff;
}

.quote-split__media { position: relative; }
.quote-split__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
}

.quote-split__panel {
  display: grid;
  place-items: center;
  padding: clamp(44px, 6vw, 88px) clamp(24px, 5vw, 76px);
}
.quote-split__inner { margin: 0; max-width: 46ch; text-align: center; }

.quote-mark { color: var(--gold); margin: 0 0 18px; line-height: 0; }
.quote-mark svg { display: inline-block; }

.quote-ar {
  font-family: var(--arabic);
  font-size: clamp(23px, 1.95vw, 29px);
  line-height: 1.42;
  direction: rtl;
  margin: 0 0 14px;
}
.quote-en {
  font-size: clamp(16px, 1.35vw, 20px);
  line-height: 1.62;
  margin: 34px 0 12px;
}
.quote-cite {
  display: block;
  font-style: normal;
  color: var(--gold-light);
  font-size: clamp(12px, 1.05vw, 14px);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.quote-cite--ar {
  font-family: var(--arabic);
  font-size: clamp(19px, 1.7vw, 25px);
  letter-spacing: normal;
  text-transform: none;
}

/* Stack on narrow screens: photo on top, quote beneath. */
@media (max-width: 899.98px) {
  .quote-split { grid-template-columns: 1fr; }
  .quote-split__media img { height: auto; max-height: 62svh; }
}

/* ---------- Specs + bulk ---------- */
.detail-grid {
  display: grid; gap: clamp(34px, 5vw, 64px);
  grid-template-columns: 1fr;
}
@media (min-width: 820px) { .detail-grid { grid-template-columns: 1.15fr .85fr; } }

.specs { margin: 0; }
.specs--wide { display: grid; gap: 0 clamp(24px, 5vw, 72px); grid-template-columns: 1fr; }
@media (min-width: 700px) { .specs--wide { grid-template-columns: 1fr 1fr; } }
.specs div { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid rgba(30,62,105,.10); }
.specs div:last-child { border-bottom: 0; }
.specs dt { font-weight: 700; color: var(--gold-light); min-width: 132px; margin: 0; }
.specs dd { margin: 0; color: var(--navy-soft); }

.bulk { text-align: center; }
.bulk h2 { font-size: clamp(24px, 3vw, 32px); margin-bottom: 6px; }
.bulk p { color: var(--gold); font-weight: 700; margin-bottom: 10px; }
.bulk .bulk__contact { color: rgba(255,255,255,.85); font-weight: 400; }
.bulk a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Bulk sales band ---------- */
.bulk-band {
  /* Tall enough for the artwork to read. With background-attachment:fixed the
     image is sized to the VIEWPORT, not the element, so a short band shows
     only a thin slice - fine for the pre-order pattern, which is a texture,
     but the stacked books are a single centred subject and were reduced to a
     fragment at the old 360px height. */
  position: relative;
  min-height: clamp(420px, 62svh, 640px);
  display: grid;
  place-items: end center;
  padding-bottom: clamp(52px, 8vh, 96px);
  color: #fff;
  background-color: var(--navy);
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  text-align: center;
}
/* The books artwork peaks at RGB(216,220,230) on the headdress, where white
   text measures 1.37:1. A navy scrim, heavy at the top where the copy sits and
   clearing by two-thirds down, keeps the text legible while letting the books
   read below it. The pre-order pattern needs no scrim - its lightest point is
   still 12.23:1. */
.bulk-band::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(0deg,
    rgba(30,62,105,.94) 0%,
    rgba(30,62,105,.88) 28%,
    rgba(30,62,105,.45) 58%,
    rgba(30,62,105,0)   82%);
}
.bulk-band > .shell { position: relative; z-index: 1; }
.bulk-band .bulk { text-align: center; }
.bulk-band h2 { color: #fff; }

/* ---------- CTA band ---------- */
.cta-band {
  min-height: clamp(360px, 48svh, 520px);
  display: grid;
  place-items: center;
  text-align: center; color: #fff;
  background-color: var(--navy);
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
}
.cta-band .availability {
  font-size: clamp(19px, 2.6vw, 30px); margin-bottom: 6px;
}
.cta-band .availability strong { color: #fff; }
.cta-band .availability span { color: var(--gold-light); }
.cta-band .ships { color: rgba(255,255,255,.72); font-size: 15px; margin-bottom: 30px; }

.button {
  display: inline-block; min-width: 210px; padding: 16px 38px;
  background: var(--yellow); color: #000; border-radius: 7px;
  font-family: var(--serif); font-size: 19px; font-weight: 700;
  letter-spacing: .04em; text-decoration: none; text-align: center;
  transition: background-color .18s ease, transform .18s ease;
}
.button:hover, .button:focus { background: #E6DA04; transform: translateY(-2px); color: #000; }
.button--ghost { background: transparent; border: 1px solid var(--yellow); color: var(--yellow); }
.button--ghost:hover, .button--ghost:focus { background: var(--yellow); color: #000; }

/* ---------- Footer ---------- */
.site-footer { background: var(--yellow); color: #000; padding-block: 42px; font-size: 15px; }
.site-footer a { color: #000; }
.footer-grid {
  display: grid; gap: 26px; align-items: center;
  grid-template-columns: 1fr; text-align: center;
}
@media (min-width: 820px) {
  .footer-grid { grid-template-columns: auto 1fr auto; text-align: left; }
  .footer-contact { text-align: right; }
}
.footer-logo img { width: 120px; margin-inline: auto; }
.footer-links { margin-top: 6px; }
.footer-links a { text-decoration: underline; text-underline-offset: 3px; }
.footer-contact a { text-decoration: none; font-weight: 700; }
.social { display: flex; gap: 10px; justify-content: center; margin-bottom: 12px; }
@media (min-width: 820px) { .social { justify-content: flex-end; } }
.social a {
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 50%; background: rgba(0,0,0,.10);
  color: #000; transition: background-color .18s ease;
}
.social a:hover, .social a:focus { background: rgba(0,0,0,.22); }
.social svg { width: 16px; height: 16px; fill: currentColor; }

/* ---------- Back to top ---------- */
.to-top {
  position: fixed; right: 22px; bottom: 22px; z-index: 60;
  width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--navy); color: #fff; border: 0; border-radius: 6px;
  cursor: pointer; opacity: 0; visibility: hidden;
  transition: opacity .22s ease, visibility .22s ease;
}
.to-top.is-visible { opacity: .92; visibility: visible; }
.to-top:hover { opacity: 1; }
.to-top svg { width: 17px; height: 17px; fill: currentColor; }

/* ==========================================================================
   IMAGE BANDS
   Collapsed via the `hidden` attribute until their artwork loads, then
   revealed by the probe in index.html, which sets background-image directly.
   This is why they carry no static url() - a CSS background cannot report a
   404, so a missing file would leave a full-height coloured void on the page.
   ========================================================================== */

.band--figure[data-bg] {
  background-color: var(--navy);
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Parallax on capable pointers only - iOS ignores background-attachment:fixed
   and jitters, which is why it is gated to fine pointers at >=900px. */
@media (min-width: 900px) and (prefers-reduced-motion: no-preference) and (pointer: fine) {
  .bulk-band, .cta-band { background-attachment: fixed; }
}
