/* ═══════════════════════════════════════════════════════════════════════════
   doc.css — the result document.

   This is the artefact a subscriber hands to their client, so it is the one
   surface that has to look like it came from a studio rather than from a tool.
   It is used by the in-app viewer, the public share link, and the printer, and
   it has to hold up in all three.

   Loaded after app.css, and it deliberately overrides the app's lighter
   chrome: a document should look like a document, not like a page of the
   application it happened to be made in.
   ═══════════════════════════════════════════════════════════════════════════ */

.doc-body {
  background:
    radial-gradient(ellipse 80% 50% at 50% -10%, rgba(138,92,246,.10), transparent 70%),
    var(--bg);
  padding: 0 0 70px;
  min-height: 100vh;
}

.doc {
  max-width: 940px;
  margin: 40px auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 0 0 46px;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* ── Masthead ─────────────────────────────────────────────────────────────*/

.doc-head {
  padding: 46px 58px 34px;
  border-bottom: 1px solid var(--border);
  position: relative;
  background:
    linear-gradient(180deg, var(--surface), transparent);
}
.doc-head::before {
  content: ''; position: absolute; inset-block-start: 0; inset-inline: 0;
  height: 4px; background: var(--grad);
}

.doc-logo {
  max-height: 60px; max-width: 220px;
  margin-bottom: 26px; display: block;
  object-fit: contain;
}

.doc-head .eyebrow { margin-bottom: 10px; display: block; }

.doc-head h1 {
  font-size: clamp(28px, 3.6vw, 42px);
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1.08;
  margin: 0 0 14px;
  color: var(--heading);
}
html[dir="rtl"] .doc-head h1 { letter-spacing: 0; line-height: 1.35; font-weight: 600; }

.doc-sub {
  color: var(--text-dim); font-size: 14px; margin: 0;
  font-family: var(--font-mono); letter-spacing: .02em;
}
html[dir="rtl"] .doc-sub { font-family: var(--font-ar); }

/* ── Body ─────────────────────────────────────────────────────────────────*/

.doc-body-inner { padding: 38px 58px 0; }
@media (max-width: 680px) {
  .doc { margin: 14px 10px; border-radius: 14px; }
  .doc-head { padding: 32px 24px 26px; }
  .doc-body-inner { padding: 28px 24px 0; }
}

.doc-body-inner h2 {
  font-size: 21px; font-weight: 600; letter-spacing: -.02em;
  margin: 42px 0 16px; padding-top: 24px;
  border-top: 1px solid var(--border);
  color: var(--heading);
  display: flex; align-items: baseline; gap: 14px;
}
html[dir="rtl"] .doc-body-inner h2 { font-weight: 600; letter-spacing: 0; }
.doc-body-inner h2:first-child { border-top: 0; padding-top: 0; margin-top: 0; }

/* Section numbering, so a long document is navigable by eye. */
.doc-body-inner { counter-reset: docsec; }
.doc-body-inner h2::before {
  counter-increment: docsec; content: counter(docsec, decimal-leading-zero);
  font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  color: var(--kf-purple); flex: none; letter-spacing: .06em;
}

.doc-body-inner h3 { font-size: 16px; font-weight: 600; margin: 26px 0 9px; color: var(--heading); font-family: var(--font-body); }
html[dir="rtl"] .doc-body-inner h3 { font-family: var(--font-ar); }
.doc-body-inner p  { color: var(--text-dim); margin: 0 0 13px; font-size: 15.2px; line-height: 1.78; }
.doc-body-inner strong, .doc-body-inner b { color: var(--heading); font-weight: 600; }
.doc-body-inner ul, .doc-body-inner ol { margin: 0 0 16px; padding-inline-start: 22px; }
.doc-body-inner li { color: var(--text-dim); margin-bottom: 8px; font-size: 15px; line-height: 1.7; }
.doc-body-inner li::marker { color: var(--kf-purple); }

/* Callout block — used per post, per direction, per section */
.doc-block {
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--kf-purple);
  border-radius: 13px;
  padding: 20px 24px;
  margin-bottom: 16px;
  background: var(--surface);
}
.doc-block h3 { margin-top: 0; }
.doc-meta {
  font-family: var(--font-mono);
  font-size: 12px !important; color: var(--text-faint) !important;
  letter-spacing: .04em;
}
html[dir="rtl"] .doc-meta { font-family: var(--font-ar); letter-spacing: 0; }

/* Figures — the numbers a client actually looks for */
.doc-stats { display: flex; gap: 14px; flex-wrap: wrap; margin: 22px 0 30px; }
.doc-stats > div {
  flex: 1; min-width: 140px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px; padding: 18px 20px;
}
.doc-stats b {
  display: block; font-family: var(--font-display);
  font-size: 1.9rem; font-weight: 700; line-height: 1.1;
  letter-spacing: -.03em; color: var(--heading);
  font-variant-numeric: tabular-nums;
}
html[dir="rtl"] .doc-stats b { font-family: var(--font-ar); font-weight: 700; }
.doc-stats span {
  font-size: 11.5px; color: var(--text-dim); font-weight: 500;
  letter-spacing: .05em; margin-top: 5px; display: block;
}

.doc-pre {
  background: var(--surface); border: 1px solid var(--border); border-radius: 13px;
  padding: 18px 20px; white-space: pre-wrap; overflow-x: auto;
  font: 13px/1.75 var(--font-mono); color: var(--text);
}

.doc-body-inner .scroll { margin-bottom: 18px; }

/* ── Footer ───────────────────────────────────────────────────────────────*/

.doc-foot {
  margin: 50px 58px 0; padding-top: 26px;
  border-top: 1px solid var(--border); text-align: center;
}
@media (max-width: 680px) { .doc-foot { margin: 36px 24px 0; } }
.doc-foot p { font-size: 13px; color: var(--text-dim); margin: 0 0 5px; }
.doc-foot-sm { font-size: 11.5px !important; color: var(--text-faint) !important; }

/* The subscriber's own mark, on a white-labelled document. Capped in height so
   a 2000px logo cannot push the byline off the page, and greyed back a little
   because a footer is a signature and not a masthead. */
.doc-foot-mark {
  display: block; max-height: 34px; max-width: 190px; width: auto;
  margin: 0 auto 10px; opacity: .85;
}

/* ── Logo control (in-app only) ───────────────────────────────────────────*/

.logo-panel { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.logo-preview {
  width: 92px; height: 62px; border: 1px dashed var(--border-strong);
  border-radius: 11px; display: grid; place-items: center;
  background: var(--surface); overflow: hidden; flex: none;
}
.logo-preview img { max-width: 84%; max-height: 78%; object-fit: contain; }
.logo-preview span { font-size: 10.5px; color: var(--text-faint); font-family: var(--font-mono); }

/* ── Print ────────────────────────────────────────────────────────────────*/

@media print {
  .doc-body { background: #fff; padding: 0; }
  .doc {
    box-shadow: none; border: 0; margin: 0; max-width: none;
    padding: 0; border-radius: 0;
  }
  .doc-head { padding: 0 0 20px; background: none; }
  .doc-head::before { display: none; }
  .doc-body-inner { padding: 0; }
  .doc-foot { margin-inline: 0; }
  .doc-body-inner h2 { break-after: avoid; }
  .doc-block, .scroll, .doc-stats { break-inside: avoid; }
  a[href]::after { content: ''; }
}

/* ══ The brand book ═══════════════════════════════════════════════════════
   A cover, a contents page, and a page break before each section. All of
   it also has to survive being printed, since "real PDF" here means the
   browser's own print dialogue rather than a library. */
.doc-cover {
  text-align: center;
  padding: 56px 20px 64px;
  border-bottom: 1px solid var(--doc-border, #e5e7eb);
  margin-bottom: 40px;
}
.doc-cover-logo { max-height: 84px; max-width: 260px; margin: 0 auto 28px; display: block; }
.doc-cover-kicker {
  font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--doc-muted, #6b7280); margin-bottom: 14px;
}
html[dir="rtl"] .doc-cover-kicker, [dir="rtl"] .doc-cover-kicker { letter-spacing: 0; text-transform: none; font-size: 13px; }
.doc-cover-title { font-size: clamp(30px, 6vw, 46px); line-height: 1.1; margin: 0 0 12px; }
.doc-cover-line  { font-size: 15px; color: var(--doc-muted, #6b7280); margin: 0 0 6px; }
.doc-cover-date  { font-size: 14px; color: var(--doc-muted, #6b7280); margin: 0; }
.doc-cover-foot  { font-size: 12px; color: var(--doc-muted, #9ca3af); margin: 34px 0 0; }

.doc-contents { margin-bottom: 40px; }
.doc-contents ol { list-style: none; counter-reset: toc; padding: 0; margin: 14px 0 12px; }
.doc-contents li {
  counter-increment: toc;
  display: flex; justify-content: space-between; gap: 14px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px dotted var(--doc-border, #e5e7eb);
}
.doc-contents li::before { content: counter(toc) "."; color: var(--doc-muted, #9ca3af); margin-inline-end: 10px; }
.doc-contents-name { flex: 1; }
.doc-contents-date { color: var(--doc-muted, #9ca3af); font-size: 12.5px; white-space: nowrap; }

/* RTL: the document, not just the text inside it */
.doc-book[dir="rtl"], .doc[dir="rtl"] { text-align: start; }
.doc-book[dir="rtl"] table, .doc[dir="rtl"] table { direction: rtl; }
.doc-book[dir="rtl"] ul, .doc-book[dir="rtl"] ol { padding-inline-start: 20px; padding-inline-end: 0; }

@media print {
  .doc-cover { break-after: page; border-bottom: 0; padding-top: 20mm; }
  .doc-contents { break-after: page; }
  .doc-section-start { break-before: page; }
  .doc-body-inner h2, .doc-body-inner h3 { break-after: avoid; }
  .doc-body-inner table, .doc-body-inner figure, .kft-card { break-inside: avoid; }
  .noprint, .doc-foot { display: none !important; }
  a[href]::after { content: ""; }   /* no printed URLs after every link */
}

/* The language switch on a shared document (D5). Small, centred, and gone when
   printed — a client reading the Arabic version does not need to be told the
   English one exists on paper. */
.doc-langs {
  margin: 0 58px 18px; text-align: center; font-size: 13px;
  color: var(--text-dim); letter-spacing: .02em;
}
.doc-langs a { color: var(--text-dim); text-decoration: underline; text-underline-offset: 3px; }
.doc-langs a:hover { color: var(--heading); }
.doc-langs strong { color: var(--heading); font-weight: 600; }
@media (max-width: 680px) { .doc-langs { margin-inline: 24px; } }

/* ── Export ───────────────────────────────────────────────────────────────
   The two buttons, and the off-screen stage the PDF route photographs. */

.doc-export { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.doc-export-msg { font-size: 12.5px; color: var(--text-faint); }

/* html2canvas photographs what it can see, so the clone has to be laid out at
   a real width — a zero-size or visibility:hidden stage comes back blank. It is
   pushed off-screen instead, and made white because a dark-theme screenshot
   inside a PDF is a page of black ink somebody has to print. */
.doc-pdf-stage {
  position: fixed; inset-inline-start: -10000px; top: 0;
  width: 794px;                   /* A4 at 96dpi, less the margins */
  background: #fff; color: #111;
  z-index: -1; pointer-events: none;
}
.doc-pdf-stage .doc,
.doc-pdf-stage .kft-card,
.doc-pdf-stage .cr-doc {
  background: #fff; color: #111; box-shadow: none; border-color: #e5e7eb;
}
.doc-pdf-stage .kft-card h3,
.doc-pdf-stage .kft-card h4,
.doc-pdf-stage h1, .doc-pdf-stage h2, .doc-pdf-stage h3 { color: #111; }
.doc-pdf-stage p, .doc-pdf-stage td, .doc-pdf-stage li, .doc-pdf-stage small { color: #333; }
.doc-pdf-stage th { color: #555; }

/* The administration half of a result page: sharing, passwords, the logo.
   Below the document and visibly secondary, because the document is what the
   subscriber came for and these are things done to it occasionally. */
.res-admin-head {
  font-size: 15px; font-weight: 600; color: var(--text-faint);
  letter-spacing: .04em; text-transform: uppercase;
  margin: 40px 0 14px; padding-top: 24px; border-top: 1px solid var(--border);
}
html[dir="rtl"] .res-admin-head { letter-spacing: 0; text-transform: none; font-size: 16px; }
.res-admin { display: grid; gap: 16px; }
.res-danger { margin-top: 28px; }
.doc-export-foot { margin-top: 18px; display: flex; justify-content: flex-end; }
.doc-raw {
  background: var(--bg); border: 1px solid var(--border); border-radius: 11px;
  padding: 16px; overflow: auto; font: 12.5px ui-monospace, Consolas, monospace;
}

/* Export on a public document: centred under the page, quiet, and gone from
   both the print and the PDF because it is .noprint like everything else. */
.doc-export-public {
  max-width: 860px; margin: 0 auto 46px; padding: 0 20px;
  justify-content: center;
}

/* ═══════════════════════════════════════════════════════════════════════════
   PRESENTATION MODE — a document that is delivered, not read by its author
   ───────────────────────────────────────────────────────────────────────────
   Every other document this shell wraps is read by the subscriber who made it,
   so the platform's chrome above it is honest: it is KF's tool, saying so.

   A brand book is sent onward, and the reader is a client looking at their own
   identity. KF's purple gradient across the top of somebody else's brand is
   the single thing a brand book must not have, and a masthead reading
   "Brand Identity · Nile Coffee · August 2026" in 14px monospace is a receipt
   rather than a cover.

   So `.doc-present` drops the platform's chrome and gives the document a cover.
   `--doc-accent` is the brand's OWN primary, set inline per document from its
   palette, and `--doc-on-accent` is whichever of black or white kf_hex_on()
   computed as readable against it. The few things that are coloured here are
   coloured with the client's colour, not ours.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The whole role system arrives inline on <html>, per document. This block is
   what a presentation shell falls back to when there is no palette to derive
   from — the app's own tokens, so nothing is unstyled — and it is the reason
   the rules below can name a brand role without also naming a fallback each
   time. Written on :root rather than on .doc-present because the reader chrome
   is outside the body. */
:root {
  --bb-primary:    var(--kf-purple);
  --bb-on-primary: #fff;
  --bb-secondary:  var(--kf-purple);
  --bb-accent-2:   var(--kf-purple);
  --bb-shell:      var(--bg);
  --bb-page:       var(--card);
  --bb-alt:        var(--surface);
  --bb-sunken:     var(--surface);
  --bb-dark:       #17161c;
  --bb-on-dark:    #fff;
  --bb-ink:        var(--text);
  --bb-ink-soft:   var(--text-soft);
  --bb-ink-faint:  var(--text-faint);
  --bb-divider:    var(--border);
  --bb-heading:    var(--heading);
  --bb-link:       var(--kf-purple);
  --bb-band-bg:    var(--surface);
  --bb-band-ink:   var(--text);
  --bb-radius:     10px;
  --bb-radius-lg:  16px;
  --bb-hair:       1px;
  --bb-air:        1;
  --bb-track:      .09em;
}

.doc-present {
  /* No purple wash behind a document about somebody else's colours — and no
     generic grey either. The ground is struck from the brand's own palette, so
     the page sheet sits on a surface that belongs to it. */
  background: var(--bb-shell);
}

/* ── A web page, not a photograph of a PDF ─────────────────────────────────
 *
 * This was a 1040px sheet with a drop shadow, floating on a tinted desk. It is
 * a faithful picture of a printed brand book and the wrong object entirely: the
 * thing a client actually opens is a URL, in a browser, at whatever width their
 * screen happens to be, and a document that answers a 2560px monitor with a
 * white rectangle in the middle of it looks like a PDF somebody forgot to
 * download.
 *
 * So the document is the page. Every band — the cover, each section, the
 * overview — runs edge to edge and carries its own ground, and the COLUMN
 * inside it stays at a measure somebody can read. Two elements, one full width
 * and one not, which is how every web page since about 2013 has been built and
 * is the shape this document should always have had.
 *
 * --bb-gutter is the inset that column keeps from the edge of the screen. It is
 * one variable because three different things have to agree on it: the section
 * column, the cover, and the negative margin anything full-bleed uses to escape
 * them. */
.doc-present {
  --bb-gutter: clamp(20px, 5vw, 64px);
  --bb-column: 1200px;
}

.doc-present .doc {
  max-width: none;
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  background: var(--bb-page);
}

/* The column every band shares. */
.doc-present .bb-sec-in,
.doc-present .doc-tp-in {
  max-width: var(--bb-column);
  margin-inline: auto;
  padding-inline: var(--bb-gutter);
}

/* ── The cover ─────────────────────────────────────────────────────────────
   Read in the order a cover is read: whose it is, what it is, when. The mark
   is given room rather than shrunk into a corner — on a brand book it is the
   subject, not the letterhead.

   And it is the page where the brand has to be unmistakable before a word is
   read. Every generated identity opening on the same white title layout was the
   clearest symptom of the document being a template with a logo dropped in, so
   the ground, the rule and the palette bar are all the brand's, and which of
   them the cover uses is decided by the brand's own design direction. */

.doc-titlepage {
  padding-block: clamp(56px, 11vh, 130px) clamp(44px, 8vh, 96px);
  padding-inline: 0;
  border-bottom: var(--bb-hair) solid var(--bb-divider);
  position: relative;
  background: var(--bb-alt);
  color: var(--bb-ink);
}

/* The cover's own column. The mark and the title sit side by side while there
   is room for both and stack when there is not — a hero, not a letterhead. */
.doc-tp-in {
  display: flex;
  align-items: center;
  gap: clamp(24px, 5vw, 56px);
  flex-wrap: wrap;
  position: relative;
  z-index: 1;
}

/* The rule across the top, in the brand's colour and at the weight the
   direction asks for: a hairline on a restrained identity, a slab on a bold
   one. */
.doc-titlepage::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  height: calc(4px + var(--bb-hair) * 1.5);
  background: var(--bb-primary);
  z-index: 2;
}

/* The brand's own pattern, tiled behind the cover.
 *
 * The identity specifies a repeating element and the subscriber generates it,
 * and it used to appear exactly once — as a swatch of itself, in the gallery,
 * captioned "The pattern". A brand book that specifies a pattern and does not
 * use one is telling a client to do something it did not do.
 *
 * Texture, not wallpaper. It is under everything, at an opacity where you
 * notice the cover has a surface rather than noticing the pattern, and the tile
 * is set large enough that a busy motif reads as a field instead of as noise.
 *
 * The var()'s fallback is what makes this free for a brand with no pattern:
 * the variable is simply not set, the image resolves to none, and the layer
 * costs an empty pseudo-element. */
.doc-titlepage::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--bb-pattern, none);
  background-repeat: repeat;
  background-size: clamp(160px, 17vw, 280px);
  mix-blend-mode: soft-light;
  opacity: .45;
}

/* Everything on the cover sits above it. Stated on the column rather than
   pushed behind with a negative z-index, because a negative one escapes the
   header on some engines and paints the pattern over the page behind it. */
.doc-titlepage > .doc-tp-in { position: relative; z-index: 1; }

/* On a filled or bleeding cover the ground is the brand's own colour, and a
   pattern at six per cent over a saturated ground is invisible. */
:root[data-band="fill"]  .doc-titlepage::after,
:root[data-band="bleed"] .doc-titlepage::after { opacity: .6; }

/* A filled cover for the directions that fill things. The whole page opens on
   the brand's primary or on its dark ground, and every colour on it is chosen
   against that rather than against white. */
:root[data-band="fill"]  .doc-titlepage { background: var(--bb-primary); color: var(--bb-on-primary); }
:root[data-band="bleed"] .doc-titlepage { background: var(--bb-dark);    color: var(--bb-on-dark); }
:root[data-band="fill"]  .doc-titlepage::before,
:root[data-band="bleed"] .doc-titlepage::before { display: none; }

:root[data-band="fill"]  .doc-tp-brand,
:root[data-band="bleed"] .doc-tp-brand,
:root[data-band="fill"]  .doc-titlepage h1,
:root[data-band="bleed"] .doc-titlepage h1,
:root[data-band="fill"]  .doc-tp-date,
:root[data-band="bleed"] .doc-tp-date { color: inherit; }
:root[data-band="fill"]  .doc-tp-date,
:root[data-band="bleed"] .doc-tp-date { opacity: .72; }

/* The title is the largest thing in the document, and on a cover that is the
   point: it is read from across a desk, not at a paragraph's distance. */
.doc-present .doc-titlepage h1 {
  font-size: clamp(2.6rem, 1.4rem + 4.4vw, 5.2rem);
  line-height: 1.02;
  letter-spacing: -.03em;
  margin: 0;
  text-wrap: balance;
}
html[dir="rtl"] .doc-present .doc-titlepage h1 { letter-spacing: 0; }

/* A quiet cover for the quiet directions: the page's own tint, one rule. */
:root[data-band="rule"] .doc-titlepage { background: var(--bb-page); }

/* The palette, across the foot of the cover. The fastest possible answer to
   "whose document is this" — and on a brand book the colours are the subject,
   so showing them before the contents page is not decoration. */
.doc-tp-bar {
  flex: 1 0 100%;
  display: flex;
  gap: 3px;
  height: 14px;
  margin-block-start: clamp(26px, 4vw, 46px);
  border-radius: calc(var(--bb-radius) / 2 + 3px);
}
.doc-tp-bar > span {
  flex: 1 1 0;
  border-radius: calc(var(--bb-radius) / 2);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
}

/* On a cover filled with the brand's own primary, the swatch OF that primary
   is invisible against it — the bar looked like it was missing its first
   colour. A plate behind the stops and a gap between them makes every one of
   them a separate chip, whichever ground the cover is on. */
:root[data-band="fill"]  .doc-tp-bar,
:root[data-band="bleed"] .doc-tp-bar {
  padding: 4px;
  background: color-mix(in srgb, currentColor 16%, transparent);
}

/* The mark's container, which is a real thing rather than a box the picture
   happens to land in. Fixed proportion, generous and consistent padding — the
   clear space a logo is entitled to — and a declared ground, because a white
   logo on a white page is invisible and that is the first thing a client sees.
   The class is switched by doc-reader.js after it measures the image. */
.doc-tp-mark {
  flex: 0 0 auto;
  width: clamp(112px, 18vw, 190px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: clamp(14px, 2.2vw, 26px);
  border: var(--bb-hair) solid var(--bb-divider);
  border-radius: var(--bb-radius);
  background: var(--bb-page);
}
.doc-tp-mark img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

/* Measured light: it needs the brand's dark ground or it disappears. */
.doc-tp-mark.is-on-dark  { background: var(--bb-dark);    border-color: transparent; }
.doc-tp-mark.is-on-brand { background: var(--bb-primary); border-color: transparent; }

/* On a cover that is already dark or already filled, the mark's own box would
   be a second rectangle inside the first. It gets the ground it is standing on
   and no border at all. */
:root[data-band="fill"]  .doc-tp-mark:not(.is-on-dark):not(.is-on-brand),
:root[data-band="bleed"] .doc-tp-mark:not(.is-on-dark):not(.is-on-brand) {
  background: transparent;
  border-color: color-mix(in srgb, currentColor 22%, transparent);
}

.doc-tp-text { flex: 1 1 300px; min-width: 0; }

.doc-tp-brand {
  margin: 0 0 .5em;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bb-primary);
}

/* A Latin brand name carries `dir="auto"`, which is right for the ORDER of its
   letters and wrong for where the line sits: on an Arabic cover it pushed
   "NILE COFFEE ROASTERS" to the left margin while the title it belongs to was
   on the right. The text still runs left to right; the line is aligned to the
   document's start rather than its own. */
html[dir="rtl"] .doc-tp-brand { text-align: right; }

/* Fraunces for the cover and the section numbers — a brand book is a printed
   object and reads as one in a serif. It is loaded by the shell for every
   document but used only here, so nothing else changes appearance. */
.doc-titlepage h1 {
  font-family: 'Fraunces', 'Cairo', Georgia, serif;
  font-size: clamp(34px, 5.5vw, 66px);
  font-weight: 500;
  font-optical-sizing: auto;
  letter-spacing: -.02em;
  line-height: 1.02;
  margin: 0;
  color: var(--bb-heading);
}
html[dir="rtl"] .doc-titlepage h1 { font-family: 'Cairo', serif; letter-spacing: 0; line-height: 1.25; }

.doc-tp-date {
  margin: 1.1em 0 0;
  font-size: .82rem;
  letter-spacing: .04em;
  color: var(--bb-ink-faint);
}

/* Nothing here. The bands inside are full width and each one insets its own
   column, which is the only way a section can carry a ground that reaches the
   edge of the screen. */
.doc-present .doc-body-inner { padding: 0; }

/* Anything in a delivered document that is NOT a band — the language switch,
   a fallback paragraph — still needs the column, or it starts at pixel zero. */
.doc-present .doc-body-inner > :not(.bb):not(.doc-foot) {
  max-width: var(--bb-column);
  margin-inline: auto;
  padding-inline: var(--bb-gutter);
}

/* ── Numbered sections ──────────────────────────────────────────────────── */

/* A band across the top of each one, so a reader scrolling a long document can
   see where one thing ends and the next begins without reading a word.

   WHICH band is the brand's decision rather than this file's. The design
   direction the identity settled on chooses between a rule, a tinted bar, a
   filled block in the primary and a full-width dark bleed — a Corporate Formal
   book and a Bright Playful one built from the same palette should not open
   their sections the same way, and before this they did. Each composition
   carries its own ink, computed against its own ground in PHP, so none of them
   is white-on-pale. */
/* A section is a band across the whole page: its own ground, its own head, and
   a column inside it. Not a rule and a margin — a reader scrolling a long
   document should be able to see where one thing ends and the next begins
   without reading a word, and on a web page that is done with ground rather
   than with a hairline. */
.bb-sec {
  scroll-margin-block-start: 76px;   /* the reader bar is fixed over the top */
  padding-block-end: calc(3.4em * var(--bb-air));
  background: var(--bb-page);
}

/* Alternating grounds. The tint is struck from the brand's own surface, so a
   coffee roastery alternates warm and a clinic alternates cool — the rhythm is
   the page's, the colour is never ours. */
.bb-sec:nth-of-type(even) { background: var(--bb-alt); }

/* The head runs edge to edge and the column inside it does not. */
.bb-sec-head {
  padding-block: calc(2.6em * var(--bb-air)) calc(1.5em * var(--bb-air));
  position: relative;
}

.bb-sec-h {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-block: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--bb-band-ink);
}

/* ── The three parts ───────────────────────────────────────────────────────
   What it stands for, how it sounds, how it looks. These are the identity; the
   other sections are working apparatus, and until now a reader could not tell
   the difference — five entries in one list, all the same shape. A part opens
   on a full-width head in the brand's own colour, with the brand's own pattern
   over it, and says which of three it is. */
.bb-part > .bb-sec-head {
  padding-block: calc(4em * var(--bb-air));
  background: var(--bb-dark);
  color: var(--bb-on-dark);
  overflow: hidden;
}

/* Everything inside takes the head's ink, and it has to be said rather than
   inherited: the document stylesheet colours paragraphs and headings by class,
   and a class beats inheritance every time. The eyebrow came out in the body
   ink — dark brown on the brand's dark ground, which is the exact fault this
   whole pass keeps finding in other places. */
.bb .bb-part > .bb-sec-head .bb-sec-h,
.bb .bb-part > .bb-sec-head .bb-sec-t,
.bb .bb-part > .bb-sec-head .bb-part-eyebrow,
.bb .bb-part > .bb-sec-head .bb-sec-icon,
.bb .bb-part > .bb-sec-head .bb-sec-n { color: var(--bb-on-dark); }

/* A part head carries no band decoration. The rule above the title and the bar
   down its edge are how a SECTION announces itself against the page ground;
   on a full-width dark block they are a hairline nobody can see, and the h2's
   own underline is a second one. */
.bb .bb-part > .bb-sec-head .bb-sec-h {
  border: 0;
  padding: 0;
  margin: 0;
}

/* The pattern, at the strength a dark ground can carry. Two places had it —
   the cover and the overview — and the part heads are the third and last: a
   document that tiles its pattern behind everything is a document nobody can
   read. */
/* The pattern is an IMAGE, not an ink: it arrives from an image model with its
   own background, so tiling it flat lays that background over the ground as
   well and the motif reads as a picture of a pattern rather than as texture in
   the surface. Blending it fixes what opacity alone cannot — soft-light keeps
   the ground's colour and lets only the motif's light and dark modulate it,
   which is what "the brand's pattern is in the surface" actually looks like. */
.bb-part > .bb-sec-head::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--bb-pattern, none);
  background-repeat: repeat;
  background-size: clamp(130px, 13vw, 210px);
  mix-blend-mode: soft-light;
  /* Lower than the light grounds, not higher. A dark surface shows a blended
     motif far more readily than a pale one, and the first attempt at .5 put a
     wall of the brand's own pattern behind its own part titles. */
  opacity: .22;
}
.bb-part > .bb-sec-head > .bb-sec-in { position: relative; z-index: 1; }

.bb-part-eyebrow {
  margin: 0 0 .7em;
  font-family: var(--font-body);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .72;
}
html[dir="rtl"] .bb-part-eyebrow { letter-spacing: 0; text-transform: none; }

/* A part's title is the largest thing in the document after the cover. Scoped
   through .bb so it outranks the four band variants, which are the same weight
   and come later in this file. */
.bb .bb-part > .bb-sec-head .bb-sec-t {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.15;
}
html[dir="rtl"] .bb .bb-part > .bb-sec-head .bb-sec-t { letter-spacing: 0; }

/* The body needs air under a full-width head, or the first line of the section
   sits against the edge of the band above it. */
.bb-sec-body { padding-block-start: calc(2em * var(--bb-air)); }

/* ── Which head the direction asks for ─────────────────────────────────────
   A Corporate Formal book and a Bright Playful one built from the same palette
   should not open their sections the same way. Four compositions, and each now
   works on the HEAD rather than on the heading, because a head is full width:
   the ones that fill fill the whole band instead of a strip inside a column,
   which is what "fill" meant all along and what the old negative-margin hack
   was trying to fake. */

/* `bar` — the default. A solid rule down the leading edge at full strength,
   because a tint alone reads as grey against a dark primary and vanishes
   against a pale one. Logical side, so it moves to the right in Arabic. */
.bb[data-band="bar"] .bb-sec-h,
.bb:not([data-band]) .bb-sec-h {
  padding-inline-start: 16px;
  border-inline-start: calc(var(--bb-hair) * 3) solid var(--bb-primary);
}

/* `rule` — for the editorial directions, which do not fill things. A heavy
   rule above the title and air around it. */
.bb[data-band="rule"] .bb-sec-h {
  padding-block-start: 16px;
  border-block-start: calc(var(--bb-hair) * 3) solid var(--bb-primary);
}

/* `fill` — the brand's primary, the whole width of the band. */
.bb[data-band="fill"] :not(.bb-part) > .bb-sec-head {
  background: var(--bb-primary);
  color: var(--bb-on-primary);
}

/* `bleed` — the brand's dark ground, the whole width of the band. */
.bb[data-band="bleed"] :not(.bb-part) > .bb-sec-head {
  background: var(--bb-dark);
  color: var(--bb-on-dark);
}

.bb[data-band="fill"] .bb-sec-head .bb-sec-h,
.bb[data-band="bleed"] .bb-sec-head .bb-sec-h { border: 0; padding: 0; }

/* A part head is the brand's dark ground, or its primary where the direction
   fills things. It is the one place in the document that is unmistakably a
   division rather than a heading. */
.bb[data-band="fill"] .bb-part > .bb-sec-head {
  background: var(--bb-primary);
  color: var(--bb-on-primary);
}

/* The middle one takes the brand's primary instead.
 *
 * Three identical dark blocks down a long page is a rhythm with one beat. The
 * second part on the primary gives the document a middle, tells the three
 * apart from the scrollbar alone, and puts the brand's actual colour on the
 * page rather than leaving it to hairlines and small rules — which was the
 * fairest complaint you could make about the old book: it documented a vivid
 * palette in beige. The ink is computed against the primary in PHP, so this is
 * safe on a pale brand and a dark one alike. */
.bb .bb-part[data-part="2"] > .bb-sec-head {
  background: var(--bb-primary);
}
.bb .bb-part[data-part="2"] > .bb-sec-head .bb-sec-h,
.bb .bb-part[data-part="2"] > .bb-sec-head .bb-sec-t,
.bb .bb-part[data-part="2"] > .bb-sec-head .bb-part-eyebrow,
.bb .bb-part[data-part="2"] > .bb-sec-head .bb-sec-icon,
.bb .bb-part[data-part="2"] > .bb-sec-head .bb-sec-n { color: var(--bb-on-primary); }

/* The section's own mark. A landmark rather than decoration: in a document
   where every header is the same shape, the glyph is what a reader recognises
   on the way back to a page they have already visited — faster than reading
   the title again. It takes the band's ink on a filled band, where the
   primary would be the same colour as what is behind it. */
.bb-sec-icon {
  flex: 0 0 auto;
  color: var(--bb-primary);
}
.bb[data-band="fill"] .bb-sec-icon,
.bb[data-band="bleed"] .bb-sec-icon,
.bb[data-band="fill"] .bb-sec-n,
.bb[data-band="bleed"] .bb-sec-n { color: inherit; }

.bb-sec-n {
  font-family: 'Fraunces', Georgia, serif;
  font-size: .92rem;
  font-weight: 500;
  color: var(--bb-primary);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
  opacity: .8;
}

/* The numeral takes the face the direction asks for. A serif numeral on a
   luxury book and a mono one on a tech book are different documents, and it is
   one of the cheapest places to say so. */
.bb[data-numeral="display"] .bb-sec-n {
  font-family: var(--font-display); font-weight: 700; font-size: 1rem; opacity: 1;
}
.bb[data-numeral="mono"] .bb-sec-n {
  font-family: var(--font-mono); font-size: .82rem; letter-spacing: .08em; opacity: .9;
}

.bb-sec-t {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 1.12rem;
  font-weight: 650;
  line-height: 1.35;
  transition: color .15s ease;
}
.bb[data-band="rule"] .bb-sec-t {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1rem + 1vw, 1.7rem);
  font-weight: 600;
  letter-spacing: -.015em;
}
html[dir="rtl"] .bb[data-band="rule"] .bb-sec-t { letter-spacing: 0; }

/* The document's own h2 counter numbers every heading, which double-numbers a
   book that already numbers its sections. Off here. */
.doc-present .doc-body-inner h2::before,
.bb .bb-sec-h::before { content: none; }

/* ── The client copy has no working apparatus, so nothing is warn-coloured ── */
.bb-client .bb-entries-warn .bb-entry { border-inline-start-color: var(--bb-primary); }

@media print {
  /* The cover gets the page to itself, the way a cover does. */
  .doc-present .doc-titlepage { break-after: page; min-height: 60vh; }
  /* The cover's rule and its pattern are the document, not decoration: a
     brand book printed without its own colour on the first page is a different
     document from the one the client was sent. */
  .doc-present .doc-titlepage::before,
  .doc-present .doc-titlepage::after { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .bb-sec-h { break-after: avoid; }
  .doc-present .doc { box-shadow: none; }
}


/* ── The cover's palette runs the full width of the page ───────────────────
   It was a 14px bar floating in the middle of the cover with 150px of nothing
   above and below it — a strip of colour with no relationship to anything. A
   brand book's cover has one job after the mark, which is to say what colour
   this brand is, and the way to say it is edge to edge along the bottom of the
   band rather than as a widget inside the column.

   `width: 100vw; margin-inline: calc(50% - 50vw)` is how an element escapes a
   centred column; the negative bottom margin cancels the cover's own padding so
   the strip sits flush against the band below it. */
.doc-titlepage { --tp-pad-b: clamp(44px, 8vh, 96px); }
/* A sibling of the cover's column rather than a child of it, so it is already
   the width of the band and needs no escape trick — 100vw counts the scrollbar
   and overflows the page by its width, which is a horizontal scrollbar on every
   screen that has a vertical one. */
.doc-present .doc-tp-bar {
  width: auto;
  margin: 0;
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 1;                      /* above the cover's pattern layer */
  height: clamp(16px, 2.4vh, 26px);
  /* A hairline along the top, or the surface stop — very often the page's
     own colour — dissolves into the cover above it. */
  border-block-start: 1px solid color-mix(in srgb, var(--bb-ink) 14%, transparent);
  gap: 0;
  border-radius: 0;
  padding: 0;
}

/* A hairline between stops. Without it the surface colour — which is very often
   the page's own colour — reads as a hole in the strip rather than as one of
   the brand's four colours, which is the opposite of what a palette says. */
.doc-present .doc-tp-bar > span {
  border-radius: 0;
  box-shadow: none;
}
.doc-present .doc-tp-bar > span + span {
  border-inline-start: 1px solid color-mix(in srgb, var(--bb-ink) 14%, transparent);
}
