/* ════════════════════════════════════════════════════════════════════
 * FG-CMS — starter stylesheet
 * ════════════════════════════════════════════════════════════════════
 *
 * A new site starts here. Three parts, in order:
 *
 *   1. Editor chrome     do not touch — the editor needs it
 *   2. Brand             CHANGE THIS. Colours and fonts, nothing else.
 *   3. Vocabulary        the shared class names, expressed in terms of
 *                        part 2, so they follow the brand automatically
 *
 * Setting part 2 correctly is most of the work of a new site. Every
 * block in the library reads these tokens, so a block installed from
 * another project arrives in this brand's colours and typefaces
 * without being edited.
 * ════════════════════════════════════════════════════════════════════ */


/* ── 1. Editor chrome ────────────────────────────────────────────────
 * Controls the editor injects into the page — add/remove buttons, block
 * tools, the colour chip. Hidden on the public site, shown when
 * body.cms-edit is set (only ever on edit.php). Leave this alone. */
.cms-list-item-add, .cms-list-item-remove, .cms-list-item-move,
.cms-block-tools, .cms-block-info, .cms-block-name, .cms-block-bg-btn,
.cms-href-btn, .cms-link-tools, .cms-link-warn, .cms-add-link,
.cms-field-color-chip, .chips-source { display: none !important; }

body.cms-edit .cms-list-item-add    { display: block        !important; }
body.cms-edit .cms-list-item-remove,
body.cms-edit .cms-list-item-move,
body.cms-edit .cms-block-tools,
body.cms-edit .cms-block-info,
body.cms-edit .cms-block-name,
body.cms-edit .cms-block-bg-btn     { display: flex         !important; }
body.cms-edit .cms-href-btn         { display: inline-block !important; }
body.cms-edit .cms-link-tools       { display: inline-flex  !important; }
body.cms-edit .cms-add-link         { display: inline-flex  !important; }
body.cms-edit .cms-link-warn        { display: inline-block !important; }
body.cms-edit .cms-field-color-chip { display: inline-flex  !important; }

/* Every editor-wrapped block must be a positioned ancestor so that
   the absolute-positioned .cms-block-tools (top-right ↑↓✕) and
   .cms-block-info (bottom-left name pill + colour chip) anchor to the
   block. Without this the pill falls back to the viewport, which
   authors see as "block name doesn't appear until refresh". */
body.cms-edit .cms-block-host { position: relative; }


/* ── 2. Brand — CHANGE THIS ──────────────────────────────────────────
 * The whole palette and type system for the site. Everything below
 * derives from these, so this is the only block that needs editing to
 * rebrand.
 *
 * The neutral values here are a working placeholder, not a design. */
:root {
  /* Grounds */
  --color-bg:           #ffffff;   /* HoL page ground */
  --color-surface:      #f8f8f8;   /* HoL tinted panel */
  --color-dark-bg:      #1c1b1a;   /* the closing CTA band — design system §2 */
  --color-on-dark:      #e4dcd1;   /* warm paper on that band */

  /* Ink */
  --color-fg:           #141414;   /* body text, headings */
  --color-fg-muted:     #464543;   /* HoL secondary text — 9.6:1 */
  --color-muted:        #78706a;   /* eyebrows, captions, meta — 4.9:1 on bg, 4.6:1 on surface */

  /* Accent — House of Lucie's brand colour, measured from its theme
     stylesheet: 19 uses, on links, buttons, fills and rules. Decorative
     and large-text use only; --color-accent-soft is the tone that
     carries small text, because #b29376 is 2.9:1 on white. */
  --color-accent:       #b29376;
  --color-accent-soft:  #8a6d4f;   /* hover / pressed, and accent-as-text — 4.8:1 */

  /* Hairlines */
  --color-border:       #d9d9d9;
  --color-border-soft:  #f2f2f2;

  /* Type. Karla covers all three roles — it is the only family
     houseoflucie.org loads. */
  --font-display: 'Karla', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-body:    'Karla', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-eyebrow: 'Karla', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* Measure and rhythm. Fluid, not flat — design system §2. */
  --maxw:            1280px;
  --space-section-y: clamp(80px, 9vw, 144px);
  --space-section-x: clamp(20px, 5vw, 72px);

  /* Nav height, used by the nav rules and the body offset below. */
  --nav-h:           76px;
}


/* ── 3. Vocabulary — shared names, this brand's values ───────────────
 * Every FG-CMS site defines these same names. A block from any project
 * uses them and lands correctly here. See BLOCK-PRIMITIVES.md.
 *
 * Change the VALUES freely to suit the brand. Do not rename them, and
 * do not delete one because nothing uses it yet — the next block
 * installed from the library may. */

/* Short aliases. Blocks written for the ADS/EADA/TIFA line ask for
   these names; blocks from the other line ask for --color-*. Both work
   because they point at the same colours. */
:root {
  --ink:    var(--color-fg);
  --paper:  var(--color-on-dark);
  --bg:     var(--color-bg);
  --accent: var(--color-accent);
  --line:   var(--color-border);
  --muted:  var(--color-muted);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: var(--font-body);
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; }

/* Section shell */
section { padding: var(--space-section-y) var(--space-section-x); }
.wrap { max-width: var(--maxw); margin: 0 auto; }
.section--dark    { background: var(--color-dark-bg); color: var(--color-on-dark); }
.section--dark .section-title { color: var(--color-on-dark); }
.section--dark .section-label { color: rgba(255,255,255,.6); }
.section--surface { background: var(--color-surface); }

/* Typography */
.section-label {
  font-family: var(--font-eyebrow);
  font-size: 12px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--color-muted);
  margin-bottom: 20px;
}
.section-title {
  font-family: var(--font-display);
  font-size: clamp(32px, 4.5vw, 56px); font-weight: 600;
  line-height: 1.08; letter-spacing: -.015em;
  margin-bottom: 28px; text-wrap: balance;
}
.section-number {
  font-family: var(--font-eyebrow);
  font-variant-numeric: tabular-nums;
  font-size: 12px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--color-accent-soft);
}
.copy {
  font-size: 17px; line-height: 1.65;
  color: var(--color-fg-muted); max-width: 68ch;
}
.copy p + p { margin-top: 1em; }

/* Controls */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-eyebrow);
  font-size: 13px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; text-decoration: none; cursor: pointer;
  padding: 14px 28px; border: 1px solid transparent;
  transition: background .2s, color .2s, border-color .2s;
}
.btn-primary { background: var(--color-accent); color: var(--color-fg); border-color: var(--color-accent); }
.btn-primary:hover { background: var(--color-accent-soft); color: #fff; border-color: var(--color-accent-soft); }
.btn-outline { background: transparent; color: var(--color-fg); border-color: var(--color-border); }
.btn-outline:hover { border-color: var(--color-fg); }
/* Blocks from the ADS line use .btn.solid for the filled variant. */
.btn.solid { background: var(--color-fg); color: var(--color-bg); border-color: var(--color-fg); }
.btn.solid:hover { background: var(--color-accent); border-color: var(--color-accent); }

/* Decoration */
.rule { width: 48px; height: 1px; background: var(--color-border); border: 0; margin-bottom: 32px; }
.card { background: var(--color-bg); border: 1px solid var(--color-border); padding: 28px; }
.chip {
  display: inline-block;
  font-family: var(--font-eyebrow);
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--color-muted);
  border: 1px solid var(--color-border); padding: 8px 14px;
}

/* Motion. shared/site.js adds .visible on scroll. Both escape hatches
   matter: without them a block carrying .reveal is invisible wherever
   the script cannot run. */
@media (hover: hover) {
  .reveal { opacity: 0; transform: translateY(24px); transition: opacity .7s, transform .7s; }
  .reveal.visible { opacity: 1; transform: none; }
  .reveal-delay-1 { transition-delay: .1s; }
  .reveal-delay-2 { transition-delay: .2s; }
  .reveal-delay-3 { transition-delay: .3s; }
  .reveal-delay-4 { transition-delay: .4s; }
}
@media (hover: none) { .reveal { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* State */
.active   { }            /* nav/tab current item — style to suit */
.is-empty { opacity: .45; }

/* ── Site nav ────────────────────────────────────────────────────────
 * shared/nav.php emits .site-nav / .nav-logo / .nav-links / .nav-cta /
 * .nav-right / .lang-switcher / .nav-hamburger, and shared/site.js
 * toggles .scrolled and .is-open on them — but the starter ships no
 * rule for any of it, so the nav renders as unstyled inline text on
 * every page. These are the CMS's own chrome names, not new names
 * invented for this site, and every value below derives from §2.
 * Design system §5. */

.site-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; gap: 28px;
  height: var(--nav-h);
  padding: 0 var(--space-section-x);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  transition: background .3s cubic-bezier(.2,.6,.2,1),
              border-color .3s cubic-bezier(.2,.6,.2,1),
              color .3s cubic-bezier(.2,.6,.2,1);
}

.nav-logo { margin-right: auto; display: flex; align-items: center; }
.nav-logo-link { display: flex; align-items: center; text-decoration: none; }
.nav-logo img { height: 32px; width: auto; max-width: none; }
/* No logo uploaded yet: the placeholder is a real editor affordance, so
   it stays clickable in edit.php but never reaches a visitor. */
.nav-logo-empty { display: none; }
body.cms-edit .nav-logo-empty {
  display: inline-block;
  font-family: var(--font-eyebrow); font-size: 12px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--color-muted);
  border: 1px dashed var(--color-border); padding: 6px 12px;
}

.nav-links { display: flex; align-items: center; gap: 32px; list-style: none; }
.nav-links a {
  font-family: var(--font-eyebrow);
  font-size: 13px; font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; text-decoration: none;
  color: var(--color-fg-muted);
  transition: color .3s cubic-bezier(.2,.6,.2,1);
}
.nav-links a:hover { color: var(--color-accent-soft); }
.nav-links a.active,
.nav-links .active > a { color: var(--color-fg); }

.nav-cta { padding: 10px 20px; font-size: 12px; }

.nav-right { display: flex; align-items: center; gap: 20px; }

.lang-switcher { display: flex; align-items: center; gap: 8px; }
.lang-option {
  font-family: var(--font-eyebrow);
  font-size: 12px; font-weight: 600; letter-spacing: .1em;
  text-decoration: none; color: var(--color-muted);
  transition: color .3s cubic-bezier(.2,.6,.2,1);
}
.lang-option:hover  { color: var(--color-accent-soft); }
.lang-option.active { color: var(--color-fg); }

/* Two-line burger, no icon font. nav.php emits three bars; the middle
   one is the hinge, so it is hidden rather than removed from markup. */
.nav-hamburger {
  display: none;
  flex-direction: column; justify-content: center; gap: 6px;
  width: 28px; height: 28px;
  background: none; border: 0; cursor: pointer; padding: 0;
}
.nav-hamburger span {
  display: block; height: 1px; width: 100%;
  background: currentColor;
  transition: transform .3s cubic-bezier(.2,.6,.2,1),
              opacity .3s cubic-bezier(.2,.6,.2,1);
}
.nav-hamburger span:nth-child(2) { display: none; }

/* Transparent over a full-bleed hero, solid once scrolled past it.
   Pages without a hero keep the solid bar from the base rule above, so
   light links never land on a light page. :has() replaces the hasHero
   selector list the design system expected in site.js — this starter's
   site.js has no such logic, and adding a second scroll observer is
   exactly what §7 says not to do. */
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) {
  /* Not fully transparent: the hero photograph here is a pale stone
     facade, and plain white links measured 1.74:1 on it. A gradient
     that is strongest under the bar and gone by its lower edge takes
     that to 4.7:1 while leaving the photograph visible. A flat panel
     would hide it; no scrim at all is unreadable. */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--color-dark-bg) 58%, transparent) 0%,
    color-mix(in srgb, var(--color-dark-bg) 48%, transparent) 70%,
    transparent 100%);
  border-bottom-color: transparent;
}
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .nav-links a,
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .lang-option {
  color: #fff;
}
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .nav-links a:hover,
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .nav-links a.active,
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .lang-option.active {
  color: #fff;
}
body:has(.cph--hero) .site-nav:not(.scrolled):not(.is-open) .nav-hamburger { color: #fff; }

/* Pages whose first block is not a full-bleed hero sit under a solid
   fixed bar and need the height back. */
body:not(:has(.cph--hero)) { padding-top: var(--nav-h); }

/* Focus is visible on every link and button — design system §9. */
.site-nav a:focus-visible,
.site-nav button:focus-visible {
  outline: 2px solid var(--color-accent-soft);
  outline-offset: 4px;
}

@media (max-width: 900px) {
  :root { --nav-h: 60px; }
  .nav-hamburger { display: flex; }
  .nav-cta { display: none; }

  /* Full-screen overlay panel, not a squeezed row. */
  .nav-links {
    position: fixed; inset: var(--nav-h) 0 0 0;
    flex-direction: column; justify-content: center; align-items: center;
    gap: 28px;
    background: var(--color-bg);
    opacity: 0; visibility: hidden;
    transition: opacity .3s cubic-bezier(.2,.6,.2,1), visibility .3s;
  }
  .site-nav.is-open .nav-links { opacity: 1; visibility: visible; }
  .site-nav.is-open { background: var(--color-bg); border-bottom-color: var(--color-border); }
  .nav-links a { font-size: 20px; letter-spacing: .06em; color: var(--color-fg); }

  /* The open panel is opaque; the transparent-over-hero rules above
     exclude .is-open, so the bar and panel keep their solid colours. */
  .site-nav.is-open .lang-option { color: var(--color-muted); }
  .site-nav.is-open .lang-option.active { color: var(--color-fg); }
  .site-nav.is-open .nav-hamburger { color: var(--color-fg); }

  .site-nav.is-open .nav-hamburger span:first-child { transform: translateY(3.5px) rotate(45deg); }
  .site-nav.is-open .nav-hamburger span:last-child  { transform: translateY(-3.5px) rotate(-45deg); }
}


/* Editor-only: colour tokens the picker offers, and the ink/paper pair
   it uses to keep text legible on a chosen background. Add or remove
   entries to change what the colour picker shows. */
:root {
  --cms-palette: var(--color-bg), var(--color-surface), var(--color-muted),
                 var(--color-accent), var(--color-fg), var(--color-dark-bg);
  --cms-ink:     var(--color-fg);
  --cms-paper:   var(--color-on-dark);
}

/* ── Cross-brand token aliases ── (bin/fgcms-token-aliases) ── */
/* Every token any block in the library asks for, mapped to this
 * brand's own palette. A name the site already defines is skipped —
 * these only fill gaps, they never override a real definition. */
:root {
  --color-muted-2:       var(--color-muted);
  --color-black:         var(--color-fg);
  --color-accent-2:      var(--color-accent);
  --color-accent-3:      var(--color-accent);
  --color-accent-4:      var(--color-accent);
  --color-accent-5:      var(--color-accent);
  --color-accent-6:      var(--color-accent);
  --red:                 var(--color-accent);
  --red-dark:            var(--color-accent-soft);
  --red-light:           var(--color-accent);
  --dark:                var(--color-fg);
  --white:               var(--color-on-dark);
  --off-white:           var(--color-bg);
  --off:                 var(--color-surface);
  --mid:                 var(--color-fg-muted);
  --light:               var(--color-muted);
  --rule:                var(--color-border);
  --font-title:          var(--font-display);
  --ifa-accent:          var(--color-accent);
  --ifa-accent-dark:     var(--color-accent-soft);
  --ifa-accent-light:    var(--color-accent);
  --ifa-white:           var(--color-bg);
  --ifa-off:             var(--color-surface);
  --ifa-dark:            var(--color-fg);
  --ifa-mid:             var(--color-fg-muted);
  --ifa-light:           var(--color-muted);
  --ifa-rule:            var(--color-border);
  --ifa-radius:          0;
  --ifa-font-title:      var(--font-display);
  --ifa-font-body:       var(--font-body);
  --font-numeral:        var(--font-display);
  --field:               var(--color-surface);
  --field-line:          var(--color-border);
  --radius:              0;
  --cm-speed:            42s;
  --h-cycle:             0;
}
/* ── end cross-brand token aliases ── */

/* ── Library block normalisation ── (bin/fgcms-library-normalise) ── */
/* Written by bin/fgcms-library-normalise. Values come from this brand's
 * own tokens, so these follow the palette rather than fixing colours. */

/* ── .btn.solid ────────────────────────────────────────────────────
   Blocks emit `btn solid` for a filled button. Sites that only define
   .btn-primary have no rule for it, so it rendered as an outline. */
.btn.solid {
  background: var(--color-fg); color: var(--color-bg);
  border-color: var(--color-fg);
}
.btn.solid:hover { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }

/* ── .btn-dark ─────────────────────────────────────────────────────
   ita_badge_note asks for a dark button. Only ITA defines one; on the
   other seven it fell through to whatever .btn gave it. */
.btn-dark {
  background: var(--color-fg); color: var(--color-bg);
  border-color: var(--color-fg);
}
.btn-dark:hover { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }

/* ── bare .btn-primary / .btn-outline ──────────────────────────────
   Three library blocks (about, hero, cinematic_cycle_timeline) write
   class="btn-primary" with no .btn beside it. On brands that put the
   box on .btn and only the colour on .btn-primary, that renders a
   filled shape with 0px of padding, and an outline button with no
   border at all — plain text. Measured on ITA and ADS.

   Adding .btn to the markup is not the fix: four brands declare .btn
   AFTER .btn-primary, so it would win on source order and repaint
   buttons that are correct today.

   :not(.btn) means correct markup is never touched, and wrapping it in
   :where() as well drops the whole selector to zero specificity — so a
   brand that already gives .btn-primary a box keeps its own numbers.
   Without that, this rule sat later in the file at equal weight and
   repainted Farmani's and Ostuni's buttons from 36px of side padding
   to 26px. It fills a gap; it never overrules. */
:where(.btn-primary, .btn-outline, .btn-dark, .btn-solid):where(:not(.btn)) {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 14px 26px;
  border: 1px solid transparent; border-radius: 0;
  font-family: var(--font-eyebrow); font-weight: 600;
  font-size: 13px; letter-spacing: .1em; text-transform: uppercase;
  text-decoration: none; cursor: pointer;
}
:where(.btn-outline):where(:not(.btn)) { border-color: var(--color-border); background: transparent; }

/* ── .link-cta ─────────────────────────────────────────────────────
   A text link with a rule beneath, used by four blocks. Only ITA had
   it; elsewhere those links read as body text. */
.link-cta {
  display: inline-flex; align-items: center; gap: 8px; padding: 4px 0;
  font-family: var(--font-eyebrow);
  font-weight: 600; font-size: 13px; letter-spacing: .1em;
  text-transform: uppercase; text-decoration: none;
  color: var(--color-fg); border-bottom: 2px solid var(--color-accent);
  transition: color .2s, border-color .2s;
}
.link-cta:hover { color: var(--color-accent); }

/* ── Tables ────────────────────────────────────────────────────────
   eada_honours_table is the only block built on a table, and no site
   styled tables at all — it rendered with browser defaults everywhere,
   including on EADA itself. Scoped to .block so page content is
   untouched. */
:where(.block) table {
  width: 100%; border-collapse: collapse; margin: 24px 0 0;
  font-family: var(--font-body); font-size: 15px; line-height: 1.5;
}
:where(.block) table th, :where(.block) table td {
  padding: 13px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}
:where(.block) table th {
  font-family: var(--font-eyebrow); font-weight: 600;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--color-muted); border-bottom-width: 2px;
  border-bottom-color: var(--color-fg);
}
:where(.block) table td { color: var(--color-fg-muted); }
:where(.block) table tr:last-child td { border-bottom: 0; }
/* A wide table must scroll inside its block rather than push the page
   sideways. */
.block .table-wrap, :where(.block) table { max-width: 100%; }
:where(.block) .table-wrap { overflow-x: auto; }

/* ── Rhythm ────────────────────────────────────────────────────────
   A heading immediately followed by a paragraph or subtitle sat on top
   of it wherever the block brought no spacing of its own.

   Wrapped in :where() on purpose. :where() contributes ZERO specificity,
   so any rule a block defines for itself beats these — they fill a gap
   and never override a decision. Written normally, `.block h2 + .copy`
   scores higher than ADS's own `.billboard .copy { margin: 34px 0 0 }`
   and silently cut every ADS block by 20px. */
:where(.block) h1 + p, :where(.block) h2 + p, :where(.block) h3 + p,
:where(.block) h1 + .copy, :where(.block) h2 + .copy, :where(.block) h3 + .copy,
:where(.block) h2 + [data-field$="subtitle"],
:where(.block) h2 + [data-field$="intro"],
:where(.block) h2 + [data-field$="body"] { margin-top: 14px; }

/* The name-then-role pair — a card title with its one line of detail
   under it — is written as h3/h4 followed by a div or a span as often
   as by a p. Those went unspaced: measured at 4px across all eight
   brands in team, the two jury grids and cinematic_jury_row, which is
   line-box leading and nothing else. Less than a paragraph gets, since
   this is a caption sitting with its heading rather than a new
   thought. */
:where(.block) h3 + div, :where(.block) h3 + span,
:where(.block) h4 + div, :where(.block) h4 + span { margin-top: 8px; }
/* ── end library block normalisation ── */

/* ── Section links land below the pinned header ──────────────────────
   shared/site.js measures whatever is pinned to the top of the window —
   nav, header, cookie bar — into --fg-nav-h, since that height changes
   with the screen and differs site to site. The `html` prefix outranks
   fixed guesses individual blocks set for themselves. */
html [data-block-id] { scroll-margin-top: calc(var(--fg-nav-h, 72px) + 12px); }
