/*
  OPULENT AURA — SITE STRUCTURE v1.0
  Produced by Hudur, Digital Presence Directorate · 2026-07-31

  ══════════════════════════════════════════════════════════════════════════════
  THIS FILE NAMES ONLY --site-* ROLES. It contains no hex, no colour keyword, no
  typeface name, and no hand-typed size. check.mjs fails the build on any of them.
  ══════════════════════════════════════════════════════════════════════════════
  It is the layer the design system does not touch. When tokens v0.3 lands, this file
  is not opened.

  Written in LOGICAL PROPERTIES throughout — inline-start / margin-inline / padding-block
  and never left/right — so W9's «the grid mirrors fully RTL, no LTR exceptions» is a
  dir attribute rather than a rebuild. The day Arabic is ruled, this file is already
  correct; a left/right build would have to be re-authored line by line.
*/

/* ═══════════════════════════════════════════════════════════════════════
   RESET — minimal, and only what the layout depends on.
   ═══════════════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  font-family: var(--site-face-support);
  font-size: var(--site-size-body);
  line-height: var(--site-leading-body);
  font-weight: 400;
  text-rendering: optimizeLegibility;
}

img, svg { max-inline-size: 100%; block-size: auto; display: block; }

/* Every heading is reset to the body size and then ASSIGNED a role size explicitly.
   Nothing inherits a size from a browser default — an unassigned size is how a page
   arrives at a sixth value nobody chose, which is exactly the T5 failure. */
h1, h2, h3, p, figure, blockquote, ul, ol {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
}
ul, ol { padding-inline-start: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

/* Ruled tokens, replacing the ring I invented before they existed. See roles.css. */
:where(a, button):focus-visible {
  outline: var(--site-focus-width) solid var(--site-focus);
  outline-offset: var(--site-focus-offset);
}

/* The skip link. Off-screen until focused, then it takes its place in the flow rather
   than floating over the header — a link that overlays content is a competing element
   the moment it appears. It carries no size role of its own: it inherits body, so it
   costs nothing against T5's five. */
.skip-link {
  position: absolute;
  inline-size: var(--site-hairline);
  block-size: var(--site-hairline);
  overflow: hidden;
  clip-path: inset(50%);
}
.skip-link:focus-visible {
  position: static;
  inline-size: auto;
  block-size: auto;
  clip-path: none;
  display: inline-block;
  margin-block-start: var(--site-s3);
}


/* ═══════════════════════════════════════════════════════════════════════
   THE SHELL — one centred column, outer margin ≥2M at every breakpoint [W1]
   ═══════════════════════════════════════════════════════════════════════ */
.shell {
  inline-size: 100%;
  max-inline-size: var(--site-shell-max);
  margin-inline: auto;
  padding-inline: var(--site-s3);          /* ×3 M = 24px, clears the ≥2M floor */
}

.column {
  max-inline-size: var(--site-column-max); /* inside the 45–75ch band [W2] */
}

.column--centred { margin-inline: auto; text-align: center; }


/* ═══════════════════════════════════════════════════════════════════════
   HEADER — the mark and the nine routes. Static: never sticky.
   ═══════════════════════════════════════════════════════════════════════
   A sticky ribbon is named in W3's rejects and, more to the point, it is a thing that
   follows the visitor down the page while they are looking at the object. It competes,
   so it does not exist here. The header scrolls away like everything else. */
.site-header {
  padding-block: var(--site-s4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--site-s3);
  align-items: baseline;
  justify-content: space-between;
}

/* ⚠️ RAISED FROM CAPTION TO TITLE AFTER A RENDERED COVERAGE MEASUREMENT.
   This was Cormorant at 12.8px — the SMALLEST identity type in the build, on all 19
   pages, and I had reported the whole build as passing WCAG without ever measuring it.
   Mi'yar's rule, and it is the one I broke: **no WCAG claim may be made for Cormorant
   text from the computed-pair table.** That table describes SOLID FILLS. Cormorant does
   not render solid at small sizes; it renders at partial coverage, and the effective
   contrast is the BLENDED colour, not the nominal 15.44:1.

   Measured on this palace, rendered, at shipping sizes (mean coverage → effective):
       Cormorant 12.8px   0.503 → 4.75      ← what the header was
       Cormorant 20px     0.556 → 5.54      ← what it is now
       Cormorant 31.25px  0.627 → 6.70
       Cormorant 39.06px  0.672 → 7.46      full peak coverage first reached here
       Arsenal   16px     0.632 → 6.77      the support face, for comparison
   Coverage rises monotonically with size and Cormorant reaches solid only around 39px.

   Raising the wordmark is a LAYOUT choice and mine to make; it is also the better
   typographic call, since a brand wordmark outranking its own nav is correct anyway.
   **It does not make the type compliant and is not recorded as doing so** — acceptance
   for identity type belongs to Mi'yar, measured per surface at shipping size. This
   reduces the worst exposure in the build; it does not close the question. */
.site-header__mark {
  font-family: var(--site-face-identity);
  font-size: var(--site-size-title);
  font-weight: 300;
  letter-spacing: var(--site-track-wordmark);
  text-transform: uppercase;
}

/* ⚠️ THE PARAGRAPH BELOW WAS TRUE AND IS NOW HISTORY — kept because the reasoning is
   still the reasoning, and deleting it would erase why the mark was ever absent.

   ITS FACT EXPIRED: «asset production sits with Wasm» stopped being true on 2026-07-31,
   when Naqsh delivered the six tiered masters. The favicon was wired from them that same
   day — so this file was already sitting beside a build that contradicted it. On
   2026-08-01 the mark was placed on the homepage (.hero-mark below).

   THAT IS THE QUIET FAILURE WORTH NAMING: nothing here was ever wrong. A correct
   decision outlived the fact it rested on, and went on reading as current. A comment
   that states a FACT needs a date; a comment that states a REASON does not.
   ─────────────────────────────────────────────────────────────────────────────────
   THE MARK IS NOT HERE, AND ITS ABSENCE IS DELIBERATE. W4 rules the artwork tier by
   rendered pixel size and W8 rules that a broken mark is worse than no mark: «until it
   ships, the wordmark initial is not an acceptable substitute — ship no favicon rather
   than a broken mark.» Asset production sits with Wasm. So the header sets the wordmark
   in the identity face as TYPE, and the favicon is omitted rather than faked.

   The mark's tier specification is in dist/asset-manifest.json under `mark_spec`, and
   EVERY FIGURE IN IT IS PARSED FROM THE TOKEN FILE AT BUILD TIME, not transcribed here.
   That is Haneen's source rule made mechanical: four of Naqsh's cards are still live on
   a superseded token file, one of them showing a ≥38px floor against the ratified 35 —
   the value that leaves 35–37px with no permitted tier — and the card looks current.
   A number this build never types is a number that cannot go stale.
   (This comment previously claimed the manifest carried the tier table while it did not.
   The claim was made true rather than deleted.) */

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--site-s3);
}

.site-nav a {
  font-size: var(--site-size-caption);
  letter-spacing: var(--site-track-label);
  text-transform: uppercase;
  padding-block: var(--site-s1);
  border-block-end: var(--site-hairline) solid transparent;
  transition: border-color var(--site-motion) var(--site-motion-ease);
}
.site-nav a:hover,
.site-nav a[aria-current="page"] { border-block-end-color: currentColor; }


/* ═══════════════════════════════════════════════════════════════════════
   FOLDS — silence is spacing, and this is where it is bought. [W3]
   ═══════════════════════════════════════════════════════════════════════
   ≥50% of every viewport-height segment must be bare ground. That is an AREA over
   rendered output and no stylesheet can assert it — the check is the render pass.
   What this file can do is make the failure hard: one idea per fold, ×24 M between
   folds, and a column that refuses to fill the shell. */
.fold {
  padding-block: var(--site-s24);
}
.fold + .fold { padding-block-start: 0; }
.fold--tight { padding-block: var(--site-s12); }

.stack > * + * { margin-block-start: var(--site-s4); }
.stack--wide > * + * { margin-block-start: var(--site-s8); }
.stack--close > * + * { margin-block-start: var(--site-s2); }


/* ═══════════════════════════════════════════════════════════════════════
   TYPE ROLES IN LAYOUT — five sizes maximum per page, counted by check.mjs
   ═══════════════════════════════════════════════════════════════════════ */
/* THE HOUSE MARK ON THE PAGE — David's Ocular Point, ruling 10, U-05 closed.

   The size comes from --site-size-mark-hero, which is derived from the RULED T1 FLOOR
   and not from the type scale — the reasoning is at its declaration in roles.css. In
   short: this length answers «which artwork file is legal», not «how big should text
   be», so it must move with the tier table and never with the type scale.

   NO max-width and NO percentage. A responsive mark is a mark whose rendered size is
   unknown, and an unknown rendered size cannot be checked against a tier table — the
   check W4 requires would become impossible to perform, not merely inconvenient. */
/* ALIGNED TO THE TYPE, NOT TO THE PAGE. Written first with `margin-inline: auto` and
   it rendered centred while the wordmark, tagline, call to action and every line of
   body copy on this page are flush left — the mark floated alone in the middle,
   detached from the words it is supposed to head. Nothing caught it: the markup was
   valid, the tier was right, the checker passed. It was visible only in the render.

   A mark that heads a left-aligned column shares that column's edge. */
.hero-mark {
  display: block;
  width: var(--site-size-mark-hero);
  height: var(--site-size-mark-hero);
}

.t-hero {
  font-family: var(--site-face-identity);
  font-weight: 300;
  font-size: var(--site-size-hero);
  line-height: var(--site-leading-display);
  letter-spacing: var(--site-track-wordmark);
  text-transform: uppercase;
}

.t-display {
  font-family: var(--site-face-identity);
  font-weight: 300;
  font-size: var(--site-size-display);
  line-height: var(--site-leading-display);
}

.t-heading {
  font-family: var(--site-face-identity);
  font-weight: 300;
  font-size: var(--site-size-heading);
  line-height: var(--site-leading-display);
}

.t-title {
  font-family: var(--site-face-identity);
  font-weight: 300;
  font-size: var(--site-size-title);
  line-height: var(--site-leading-display);
}

.t-body { font-size: var(--site-size-body); }

.t-caption {
  font-size: var(--site-size-caption);
  letter-spacing: var(--site-track-label);
  text-transform: uppercase;
}

.t-lead { font-weight: 700; }

/* Cormorant's hairline does not reach a whole pixel until 44px — Mi'yar, recorded in
   the token file. Below that it rasterises at partial transparency and the MEASURED
   contrast overstates what the eye receives. So the identity face is used at title size
   and above and never for a run of body text, which is also T2's rule («Cormorant =
   display/identity only») arrived at from the other direction. The two agree, and where
   a typographic rule and a physical measurement agree the rule is safe to build on. */


/* ═══════════════════════════════════════════════════════════════════════
   THE OBJECT SLOT — the shape of what is not here yet.
   ═══════════════════════════════════════════════════════════════════════
   The object is unfinished and no photograph of it is approved. The Founder asked for a
   site that «lacks only displaying the products», so the slot is built to its final
   dimensions and left empty rather than filled with a placeholder.

   NO «coming soon», no skeleton shimmer, no camera glyph, no diagonal-cross box. Every
   one of those is an element competing for attention on a page whose whole argument is
   that nothing competes with the object — and a shimmer is also a second animated thing
   in the fold. An empty slot reads as space, which is what the standard wants anyway.

   The slot reserves its space with aspect-ratio, so when a real <img width height> of
   the same ratio lands the layout does not move by one pixel. That is W6's «zero layout
   shift from image loading» bought at build time rather than hoped for at load time.

   Every slot carries data-oa-slot and data-oa-subject and is emitted into
   asset-manifest.json for the producer — the house can see exactly what is missing and
   at what dimensions, while the visitor sees quiet ground. */
/* ⚠️ THE FOUR NUMBERS BELOW ARE [HDR] — MY OWN PICKS, TRACED TO NO STANDARD.
   Tagged after an audit under Haneen's source rule found them carrying no provenance at
   all, which is the same defect as an untagged token: a value nobody can argue with
   because nobody can find where it came from.

   The three ratios are NOT ruled anywhere. The P-series governs what a photograph must
   contain — single source light, ≥50% negative space, no pure-white regions — and says
   nothing about its shape. So these are a builder's choice standing in for a decision
   that has not been taken, and they are the ONE thing in this build a photographer could
   be handed and find wrong. They are recorded in asset-manifest.json against each slot
   so the producer sees a proposal rather than a specification.
   → If the object's photography wants a different frame, THESE CHANGE. Not mine to rule.

   0.18 is the slot's opacity: high enough to read as reserved space to anyone inspecting
   the page, low enough not to become an element competing in the fold [W3]. */
/* 🔴 THE VISIBLE FRAME IS REMOVED — Haneen, ruled:
   «The site does not announce its own incompleteness anywhere. No "coming soon", and NO
    EMPTY PICTURE FRAME. A page designed as text ships as text. A page that genuinely
    needs the object is NOT PUBLISHED empty — because a page that has not been built yet
    is not the same thing as a page that says it has not been built.»

   I had drawn the slot as a hairline box at 0.18 opacity and argued it read as «quiet
   ground». **It did not. It read as an empty picture frame**, which is the thing the
   ruling names — and Haneen saw one on the homepage in the render. A frame around
   nothing is a caption saying «a photograph is missing here», written in geometry
   instead of words. My reasoning was that a placeholder must not compete for attention;
   the ruling is stricter and correct: it must not ANNOUNCE, at any volume.

   The slot now paints nothing at all. It reserves its space and is otherwise invisible,
   so the layout does not move when a photograph lands (W6) and no reader is told what
   is missing. The subject and dimensions survive in `data-oa-slot` and in the asset
   manifest, where the producer reads them and the visitor does not. */
.slot {
  inline-size: 100%;
}
.slot[data-ratio="4x5"] { aspect-ratio: 4 / 5; }   /* [HDR] portrait — the bottle alone */
.slot[data-ratio="3x2"] { aspect-ratio: 3 / 2; }   /* [HDR] landscape — the set, closed */
.slot[data-ratio="1x1"] { aspect-ratio: 1 / 1; }   /* [HDR] square — detail, engraving */

.slot-frame { max-inline-size: var(--site-column-max); margin-inline: auto; }


/* ═══════════════════════════════════════════════════════════════════════
   THE COLLECTION INDEX — a world, not a grid. [Site Copy §2]
   ═══════════════════════════════════════════════════════════════════════
   «Never a comparison table. Never a filter by gender as a first-class control.»
   So: no table, no filter, no sort, no card with a border. Eleven entries in a single
   column, each showing only number, name and one line — which is what the record
   specifies and, not coincidentally, the only shape that cannot become a catalogue. */
.inhabitants { max-inline-size: var(--site-column-max); }
/* AUTO, as a positive requirement rather than an absent height — a twelfth inhabitant,
   or a longer character line, must lengthen its row instead of being clipped. [NSQ] */
.inhabitants > li { block-size: var(--site-collection-item-height); }
.inhabitants > li + li { margin-block-start: var(--site-s8); }

.inhabitant-link { display: block; }
.inhabitant-link__code {
  font-size: var(--site-size-caption);
  letter-spacing: var(--site-track-label);
}
.inhabitant-link__name {
  font-family: var(--site-face-identity);
  font-weight: 300;
  font-size: var(--site-size-title);
  line-height: var(--site-leading-display);
  margin-block-start: var(--site-s1);
  border-block-end: var(--site-hairline) solid transparent;
  display: inline-block;
  transition: border-color var(--site-motion) var(--site-motion-ease);
}
.inhabitant-link:hover .inhabitant-link__name { border-block-end-color: currentColor; }
.inhabitant-link__line { margin-block-start: var(--site-s2); }


/* ═══════════════════════════════════════════════════════════════════════
   THE INHABITANT PAGE — one structure, eleven times.
   Messaging Architecture §3 order, and the order is not a layout choice.
   ═══════════════════════════════════════════════════════════════════════ */
.notes { display: flex; flex-wrap: wrap; gap: var(--site-s1) var(--site-s3); }
.notes__stage { font-size: var(--site-size-caption); letter-spacing: var(--site-track-label); }

.facts { font-size: var(--site-size-caption); letter-spacing: var(--site-track-label); }

/* «In conversation with» — the cheapest possible expression of the house's central
   idea, per the architecture record. It is a link pair, not a «you may also like». */
.conversation a {
  border-block-end: var(--site-hairline) solid currentColor;
  transition: opacity var(--site-motion) var(--site-motion-ease);
}
.conversation a:hover { opacity: 0.7; }


/* ═══════════════════════════════════════════════════════════════════════
   THE ONE CALL TO ACTION — a line of type, not a button.
   ═══════════════════════════════════════════════════════════════════════
   The entry sequence is object → character → birth → acquisition, and the transaction
   is «the least interesting thing that happens here». A filled button would make it the
   loudest element in the fold. */
.cta {
  display: inline-block;
  font-size: var(--site-size-caption);
  letter-spacing: var(--site-track-label);
  text-transform: uppercase;
  padding-block-end: var(--site-s1);
  border-block-end: var(--site-hairline) solid currentColor;
  transition: opacity var(--site-motion) var(--site-motion-ease);
}
.cta:hover { opacity: 0.7; }


/* ═══════════════════════════════════════════════════════════════════════
   THE CREED — /house. A rule above each line, gold as ORNAMENT not letterform.
   ═══════════════════════════════════════════════════════════════════════ */
.creed > li + li { margin-block-start: var(--site-s8); }
.creed__rule { border: 0; border-block-start: var(--site-hairline) solid var(--site-accent);
               inline-size: var(--site-s6); margin: 0 0 var(--site-s3) 0; }
/* On a dark ground gold is legal as text at ×1.41 and legal as a line everywhere. This
   is a line, so it is legal on every ground the site uses — which is why the creed can
   keep it when /house is re-grounded. */


/* ═══════════════════════════════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════════════════════════════
   No newsletter field, no social row, no payment badges, no «as seen in». Each is
   refused by the architecture record by name or by W3's harm clause. What remains is
   the routes and the line. */
.site-footer {
  padding-block: var(--site-s12);
  margin-block-start: var(--site-s16);
  border-block-start: var(--site-hairline) solid currentColor;
}
.site-footer__line { font-size: var(--site-size-caption); letter-spacing: var(--site-track-label); }


/* ═══════════════════════════════════════════════════════════════════════
   BREAKPOINTS — two, and the type steps rather than scales fluidly.
   ═══════════════════════════════════════════════════════════════════════
   A clamp() between two steps would produce a continuum of sizes, and W2 requires ONE
   DECLARED SCALE whose values are generated from a ratio. A fluid size is not on the
   scale at any viewport but two — so the page would carry sizes the system cannot
   generate, which is the exact defect Mi'yar rejected in the pushed design system.
   Stepping between declared members keeps every rendered size a scale member, and keeps
   the T5 count checkable at each breakpoint instead of unknowable. */
@media (min-width: 48rem) {
  .shell { padding-inline: var(--site-s6); }
  .t-hero { font-size: var(--site-size-hero-lg); }
}

@media (min-width: 75rem) {
  .shell { padding-inline: var(--site-s8); }
}

/* Produced by: Hudur — Digital Presence Directorate */
