/* sheet.css — Fairsheet per-fund detail page.
   A4 portrait, locked dimensions, scaled to ~125% on screen for sharper
   visuals while preserving the print aspect ratio (1.414:1). PDF/print
   gets the true-A4 path below.
*/

/* Ampersand override — Playfair Display's italic-swash "&" renders as a
   stylised "et" ligature that's hard to read at a glance. This face only
   covers U+0026 (the ampersand codepoint) and falls back to a clean sans
   glyph from the OS. Browsers pick this @font-face for "&" because its
   unicode-range is more specific than the base Playfair face. */
@font-face {
  font-family: "Playfair Display";
  src: local("Georgia"), local("Cambria"), local("Times New Roman"), local("Times");
  font-weight: 100 900;
  font-style: normal;
  unicode-range: U+0026;
}
@font-face {
  font-family: "Playfair Display";
  src: local("Georgia"), local("Cambria"), local("Times New Roman"), local("Times");
  font-weight: 100 900;
  font-style: italic;
  unicode-range: U+0026;
}

/* amp.js wraps each "&" in a span so we can size it down a notch from
   its surrounding text (no weight override — let the font's own weight
   carry through). */
.amp {
  font-size: 0.94em;
}

/* Kill the default 8px browser body margin — without this the grey body
   shows through as a frame around the topbar and the printable sheet. */
html, body { margin: 0; padding: 0; }

/* ───────────────────────────────────────────────────────────────────────
   PDF / print: declare A4 paper, hide the shadow + grey background, and
   force one page-break per .page section so the two-section FairSheet
   outputs as a clean 2-page PDF. .page itself keeps its 875×1238 screen
   dimensions — Playwright's gen_pdfs.py renders at scale=0.907 so the
   natural-size layout maps exactly onto an A4 sheet without triggering
   the 920px mobile breakpoint or overflowing the print page height.
   ─────────────────────────────────────────────────────────────────────── */
/* PDF page size matches .page exactly (875×1238px = 231×328mm,
   A4 aspect ratio). Set in mm because Chromium's @page parser quietly
   falls back to A4 when given px lengths. Paired with `prefer_css_page_size=True`
   in gen_pdfs.py so one .page section paginates to one PDF page; on
   A4 paper, printers fit-to-page automatically. */
/* Exact px → mm conversion at 96dpi: 875px = 231.51mm, 1238px = 327.55mm.
   Using the precise mm values avoids the ~2.3px gap at the bottom of the
   page (where the red finisher strip would otherwise hang above the page
   floor) and the ~1.9px gap on the right edge. */
@page { size: 231.51mm 327.55mm; margin: 0; }

@media print {
  /* !important: non-media .sheet-wrap / .page rules later in the cascade
     (sized for screen) would otherwise win the same-specificity tie-break. */
  body.page-sheet { background: white !important; margin: 0 !important; padding: 0 !important; }
  /* Chromium's print engine paginates flex containers unpredictably.
     Forcing block layout restores natural top-aligned pagination. */
  .sheet-wrap   { display: block !important; padding: 0 !important; gap: 0 !important; }
  .page {
    box-shadow: none !important;
    margin: 0 !important;
    page-break-inside: avoid;
  }
  /* Hide the red finisher strip entirely in print — Chromium's print
     engine leaves a ~1.6 CSS px sub-pixel buffer between any positioned
     element and the actual page edge that no CSS hack reliably defeats.
     Rather than show a "sliver of white below the red strip", drop the
     strip from PDFs altogether. It still renders on screen / mobile. */
  .page::after { display: none !important; }
  /* Crisp logos: the DFO mark is a 512×512 PNG being downscaled to
     24-64px. Chromium's default bicubic resample blurs thin strokes at
     this ratio. -webkit-optimize-contrast picks the sharper Lanczos
     downsample path so the hex outline reads clean in print. */
  .footer-logo, .dfo-logo-header {
    image-rendering: -webkit-optimize-contrast !important;
  }
  /* Drop the soft red drop-shadow on the "Discuss with our research team"
     CTA — on screen it's a subtle lift, but Chromium's PDF rasteriser
     blooms the rgba(var(--brand-red-rgb), 0.18) shadow into a visible pink halo
     around the button. The button itself reads fine without it. */
  .contact-btn-strip { box-shadow: none !important; }
}

/* Accessibility: hide visually but keep available for screen readers
   and crawlers (used by SEO breadcrumbs that don't need to render). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
  white-space: nowrap;
}

@font-face {
  font-family: "Playfair Display";
  font-weight: 400 900;
  font-style: normal;
  src: url("/static/fonts/PlayfairDisplay-VariableFont_wght.ttf")
       format("truetype-variations");
  font-display: swap;
}

body.page-sheet {
  background: #d8d7d4;
  color: #1a1a1a;
  /* Exo 2 Light (weight 300) — base body weight. */
  font-family: "Exo 2", "Source Sans 3",
               -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 300;
  font-size: 12px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* <strong> = Exo 2 SemiBold (weight 600). Used for fund/company names
   that CH marked bold in the source Excel rich-text. */
.page-sheet strong { font-weight: 600; }

.sheet-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
  padding: 30px 0 80px;
}

/* ──────────────────────────────────────────────────────────────────────
   PAGE — A4 portrait at 125% zoom
   875 × 1238 keeps the 1:1.414 ratio (700×990 × 1.25).
   ────────────────────────────────────────────────────────────────────── */

.page {
  width: 875px;
  height: 1238px;
  background: white;
  box-shadow: 0 5px 22px rgba(0,0,0,0.12);
  position: relative;
  display: flex;
  flex-direction: column;
  font-size: 12px;
  line-height: 1.5;
  overflow: hidden;
  /* Vertical-spacing multiplier — JS in sheet.js ratchets this down from
     1.0 in 6% steps (to a 0.7 floor) only when CH's prose pushes content
     past the 1238px page height. Default 1.0 means no compression for
     short-text funds. Applied to vertical margins/padding/gaps only —
     never to font-size or line-height, so type stays legible. */
  --vspace: 1;
}

/* Bottom red finisher strip (halved thickness) */
.page::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 4px;
  background: var(--brand-red);
}

/* ──────────────────────────────────────────────────────────────────────
   Grey banner header
   ────────────────────────────────────────────────────────────────────── */

.page-banner {
  background: #ececea;
  /* Horizon strip flush to the top; rest of banner content sits below.
     Slightly narrower than the prior 32px bottom padding. */
  padding: 0 60px calc(22px * var(--vspace));
  border-bottom: 1px solid #d4d4d0;
}

/* Horizon markers strip — sits at the very top edge of the page.
   Each marker is an OUTLINED rectangle in its horizon color (white
   inside). The active horizon is solid-filled + slightly taller, with
   the "FairHorizon <Name>" label centered beneath it. */
.horizon-strip {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  column-gap: 8px;
  align-items: start;
  padding-top: 0;
  margin: 0 -60px calc(22px * var(--vspace));  /* extends edge-to-edge */
  padding: 0 60px;
}
.hmark { display: flex; flex-direction: column; align-items: stretch; }
/* Each marker = a half-height rectangle with NO top border (so it
   reads as a tab "rising out" of the page edge), left/right/bottom
   borders colored per horizon. Inactive markers have transparent
   fill — the banner's grey shows through, so they look colorless. */
.hmark-bar {
  height: 8px;                       /* halved from 16px */
  border-left:   1.4px solid transparent;
  border-right:  1.4px solid transparent;
  border-bottom: 1.4px solid transparent;
  border-top:    0;                  /* top edge unshaded */
  box-sizing: border-box;
  background: transparent;           /* banner grey shows through */
}
.hmark.h-purple .hmark-bar { border-color: var(--horizon-purple); }
.hmark.h-blue   .hmark-bar { border-color: var(--horizon-blue); }
.hmark.h-green  .hmark-bar { border-color: var(--horizon-green); }
.hmark.h-yellow .hmark-bar { border-color: var(--horizon-yellow); }
.hmark.h-orange .hmark-bar { border-color: var(--horizon-orange); }
.hmark.h-red    .hmark-bar { border-color: var(--horizon-red); }
/* Active marker: solid horizon-color fill, taller, still no top border */
.hmark.is-active .hmark-bar { height: 11px; }   /* halved from 22px */
.hmark.is-active.h-purple .hmark-bar { background: var(--horizon-purple); }
.hmark.is-active.h-blue   .hmark-bar { background: var(--horizon-blue); }
.hmark.is-active.h-green  .hmark-bar { background: var(--horizon-green); }
.hmark.is-active.h-yellow .hmark-bar { background: var(--horizon-yellow); }
.hmark.is-active.h-orange .hmark-bar { background: var(--horizon-orange); }
.hmark.is-active.h-red    .hmark-bar { background: var(--horizon-red); }
.hmark-label {
  font-family: "Exo 2", "Source Sans 3", sans-serif;
  font-size: 11px;
  text-align: center;
  color: #1a1a1a;
  margin-top: 6px;
}

.page-banner-body {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 40px;
  align-items: center;        /* DFO logo vertically centered to the title block */
}
.head-left { flex: 1; min-width: 0; }
.fund-code {
  font-family: "Exo 2", "Source Sans 3", sans-serif;
  font-size: 15px;
  color: #1a1a1a;
  margin-bottom: 5px;
}
/* The -I / -F / -A management-style suffix is secondary metadata; ride
   at half opacity so the underlying code (B14, R55, etc.) stays the
   visual anchor. */
.fund-code .code-suffix { opacity: 0.7; }
.fund-name {
  font-family: "Playfair Display", serif;
  font-weight: 400;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.005em;
  margin: 0 0 calc(10px * var(--vspace));
  max-width: 520px;
}
.fund-tag {
  font-family: "Exo 2", "Source Sans 3", sans-serif;
  font-style: italic;
  font-size: 12px;
  color: #1a1a1a;
  max-width: 520px;
  margin: 0;
  line-height: 1.5;
}
.dfo-logo-header {
  height: 64px;          /* between 56 and 72 */
  width: auto;
  display: block;
}

/* Banner head-right stacks the logo above the download button, both
   right-aligned. The button is a soft, subdued pill that sits within
   the brand palette without competing with the fund name on the left. */
.head-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}
.pdf-download {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(var(--brand-red-rgb), 0.06);
  border: 1px solid rgba(var(--brand-red-rgb), 0.18);
  color: var(--brand-red);
  text-decoration: none;
  font-family: "Exo 2", "Source Sans 3", sans-serif;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
}
.pdf-download:hover {
  background: var(--brand-red);
  border-color: var(--brand-red);
  color: #ffffff;
}
.pdf-download-icon {
  display: block;
  flex-shrink: 0;
}
.pdf-download-label { display: inline-block; }
@media screen and (max-width: 720px) {
  .pdf-download-label { display: none; }   /* icon-only on narrow viewports */
  .pdf-download { padding: 8px 10px; }
}
@media print {
  .pdf-download { display: none !important; }
}

/* ──────────────────────────────────────────────────────────────────────
   White body
   ────────────────────────────────────────────────────────────────────── */

.page-body {
  flex: 1;
  padding: calc(22px * var(--vspace)) 60px calc(22px * var(--vspace));
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.date-stamp {
  text-align: right;
  font-style: italic;
  font-size: 12px;
  color: #1a1a1a;
  margin: 0;
  font-weight: 200;
}

/* Header row: "About the Fund" left, date stamp right, same baseline.
   Closes the white space between header and row content. */
.about-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  margin: 0 0 calc(6px * var(--vspace));
}
.about-head .section-title { margin: 0; }
.about-head .date-stamp    { margin: 0; }

.section-title {
  font-family: "Playfair Display", serif;
  font-weight: 400;
  font-size: 18px;
  margin: 0 0 calc(10px * var(--vspace));
  color: #1a1a1a;
}
.section-title-center { text-align: center; margin-bottom: calc(14px * var(--vspace)); }
/* Used for "About the Fund" — sits as a flushed-up full-width header
   above its row, so the body prose and the meta-title (next to it in
   the row) start on the same horizontal line. */
.section-title-flush {
  margin: 0 0 calc(8px * var(--vspace));
}
/* Drawdown title stays on one line. The h2 takes its column's full
   width so text-align:right anchors the title's right edge to the right
   column's right margin (= page-body right padding). If the text is
   wider than the column at 16px, it overflows leftward into the gap
   between the two columns — well clear of "Why we prefer this fund"
   on the left, since that title is much shorter. */
.section-title-nowrap {
  white-space: nowrap;
  text-align: right;
}
@media (max-width: 920px) {
  /* On mobile the column is full-width — left-align like every other title. */
  .section-title-nowrap { text-align: left; }
}

/* Both row-why headings drop a step (18px → 16px) so the drawdown title
   needs less horizontal room and visually balances with the slightly
   shorter "Why we prefer this fund" heading next to it. */
.row-why .section-title { font-size: 16px; }

.row { display: grid; gap: 32px; margin-bottom: calc(22px * var(--vspace)); }
.row-about    { grid-template-columns: 1.3fr 1fr; }
.row-perf     { grid-template-columns: 1.5fr 1fr; }
.row-returns  { grid-template-columns: 1fr 1fr 1fr; gap: 28px; margin-top: calc(10px * var(--vspace)); }
.row-returns.row-returns-cols-1 { grid-template-columns: minmax(0, 56%); }
.row-returns.row-returns-cols-2 { grid-template-columns: 1fr 1fr; }
.row-returns.row-returns-cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.row-why      { grid-template-columns: 1fr 1fr; }
.col { min-width: 0; }

.about-prose p {
  margin: 0 0 calc(9px * var(--vspace));
  font-size: 12px;
  line-height: 1.55;
}
/* Bolded names/terms in the About-the-Fund prose pick up the active
   FairHorizon accent — adds a horizon-coded visual anchor for CH's
   richtext **bold** markers. */
.about-prose strong { color: var(--accent); }

/* ──────────────────────────────────────────────────────────────────────
   Two-stage prose-size shrinker. Applied by sheet.js when the --vspace
   ratchet has already bottomed at 0.45 and the page is *still* taller
   than the 1238px bound — typically a long German translation of CH's
   English about/why prose. Each level pulls the editorial prose tighter
   without touching numerical / chart / meta-box typography.
   ────────────────────────────────────────────────────────────────────── */
.page.is-shrunk-1 .about-prose p,
.page.is-shrunk-1 .returns-narrative,
.page.is-shrunk-1 .row-why .col p {
  font-size: 11.5px;
  line-height: 1.5;
}
.page.is-shrunk-2 .about-prose p,
.page.is-shrunk-2 .returns-narrative,
.page.is-shrunk-2 .row-why .col p {
  font-size: 11px;
  line-height: 1.48;
}
.page.is-shrunk-3 .about-prose p,
.page.is-shrunk-3 .returns-narrative,
.page.is-shrunk-3 .row-why .col p {
  font-size: 10.5px;
  line-height: 1.45;
}

.meta-box { font-size: 12px; display: flex; flex-direction: column; }
.meta-title {
  font-family: "Exo 2", "Source Sans 3", sans-serif;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  margin: 0 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #d6d6d2;
  max-width: 300px;
}
.meta-list {
  margin: 0;
  display: grid;
  /* Label column sized to fit the longest label exactly (no shrinking),
     value column gets the remaining space — and is the only one that's
     allowed to wrap when its content runs long (e.g. "Global multi-asset
     moderate defensive" in the P3D 40/60 meta box). */
  grid-template-columns: max-content 1fr;
  /* Each grid row's dd centres vertically against its dt. Matters most
     for multi-line labels (e.g. "Max. Recommended / Portfolio Share")
     where the single-line value would otherwise hug the top of the cell. */
  align-items: center;
  row-gap: calc(7px * var(--vspace));
  column-gap: 16px;
  font-size: 12px;
}
.meta-list dt {
  color: #1a1a1a;
  white-space: nowrap;           /* row labels NEVER wrap */
}
.meta-list dd {
  margin: 0;
  text-align: right;
  min-width: 0;                  /* let the value wrap inside its column */
}
.meta-list.compact { row-gap: calc(4px * var(--vspace)); margin-top: calc(10px * var(--vspace)); }

/* ──────────────────────────────────────────────────────────────────────
   Performance chart
   ────────────────────────────────────────────────────────────────────── */

.chart-caption {
  font-weight: 600;
  font-size: 12px;
  margin: 0 0 8px;
}
/* overflow:hidden — without this, Chrome's PDF print engine sometimes
   rasterises the canvas at its intrinsic device-pixel buffer width
   rather than the CSS width, letting the chart line + tick labels bleed
   into the column to its right and across the page edge. */
.chart-wrap { position: relative; height: 190px; width: 100%; overflow: hidden; }
.chart-wrap-tall { height: 206px; }
.chart-wrap canvas {
  max-width: 100%;
  max-height: 100%;
}
.chart-placeholder {
  height: 190px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed #d6d6d2;
  color: #8a8a8a;
  font-size: 12px;
}

/* ──────────────────────────────────────────────────────────────────────
   FairHorizon Context

   Layout layers from bottom to top:
     1. Grey horizontal strip per row (.band-row background)
     2. Each row's colored bar (.band-row::after) — outlined rectangle
        with sparse-but-dense diagonal stripes inside; solid fill for active
     3. A SINGLE absolutely-positioned overlay (.band-grid-overlay) draws
        the vertical demarcation lines from above the first row down to
        the bottom of the last row, cutting through everything visually
        for a continuous time-horizon grid with a small stick-out at the
        top.
   ────────────────────────────────────────────────────────────────────── */

.band-grid { position: relative; }

.band-labels {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  font-size: 11px;
  color: #9a9a96;          /* greyed-out */
  margin-bottom: 1px;      /* sit closer to the bars */
}
.band-labels span {
  text-align: center;       /* centered within each cell */
  padding-left: 0;
}

.band-rows {
  position: relative;
  padding-top: 4px;            /* room for the vertical-line stick-out */
}

.band-row {
  position: relative;
  height: 14px;
  margin-bottom: 5px;          /* 1.5× of the previous 3px between bars */
  background-color: #ececea;
}
.band-row:last-of-type { margin-bottom: 0; }

/* Colored bar overlay: outlined rectangle with evenly-spaced diagonal
   stripes. 2px line + 2px gap = 4px cycle — EVERY length is a whole
   integer pixel so Chromium/Safari/Firefox snap stripes to the same
   device-pixel grid. The 2.5px sub-pixel cycle was causing the stripes
   on shorter band-rows (orange/red) to render heavier than the taller
   ones because the rasterizer was choosing different sample phases per
   row. Coverage is 50% (was ~30%), so the bands read visibly denser
   while the lines stay crisp and consistent across every row. */
.band-row::after {
  content: "";
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: var(--band-w, 100%);
  box-sizing: border-box;
  border: 1px solid var(--horizon-color);
  background-color: white;
  background-image: repeating-linear-gradient(
    -45deg,
    var(--horizon-color) 0,
    var(--horizon-color) 2px,
    transparent 2px,
    transparent 4px
  );
}
.band-row.is-active::after {
  background-image: none;
  background-color: var(--horizon-color);
}
/* Active band sits on top of the vertical grid overlay so the solid
   horizon bar reads as one uninterrupted block. Inactive (striped) bands
   stay under the grid lines, which keeps the time-horizon column breaks
   readable across the rest of the chart. */
.band-row.is-active { z-index: 2; }

.band-row.h-purple { --horizon-color: var(--horizon-purple); }
.band-row.h-blue   { --horizon-color: var(--horizon-blue); }
.band-row.h-green  { --horizon-color: var(--horizon-green); }
.band-row.h-yellow { --horizon-color: var(--horizon-yellow); }
.band-row.h-orange { --horizon-color: var(--horizon-orange); }
.band-row.h-red    { --horizon-color: var(--horizon-red); }

.band-w-1 { --band-w: calc(100% / 6); }
.band-w-2 { --band-w: calc(2 * 100% / 6); }
.band-w-3 { --band-w: calc(3 * 100% / 6); }
.band-w-4 { --band-w: calc(4 * 100% / 6); }
.band-w-5 { --band-w: calc(5 * 100% / 6); }
.band-w-6 { --band-w: 100%; }

/* Continuous vertical grid overlay — last child of .band-rows, so it
   paints on top of the rows AND the colored bars. Spans from 0
   (=4px above first row, the stick-out) to the bottom of the last
   row. */
.band-grid-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(100% / 6 - 1px),
    #9a9a96 calc(100% / 6 - 1px),
    #9a9a96 calc(100% / 6)
  );
}

.exp-list {
  margin: calc(14px * var(--vspace)) 0 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  row-gap: calc(6px * var(--vspace));
  column-gap: 16px;
  font-size: 12px;
  padding-top: calc(10px * var(--vspace));
  border-top: 1px solid #d6d6d2;
}
.exp-list dt { color: #1a1a1a; white-space: nowrap; }
.exp-list dd { margin: 0; text-align: right; min-width: 0; }

/* ──────────────────────────────────────────────────────────────────────
   Returns 3-column block
   ────────────────────────────────────────────────────────────────────── */

.returns-col { font-size: 12px; display: flex; flex-direction: column; }
.returns-title {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px;
  font-weight: 600;
  margin: 0 0 calc(7px * var(--vspace));
  padding-bottom: calc(7px * var(--vspace));
  border-bottom: 1px solid #d6d6d2;
}
.rt-mark { display: inline-block; width: 28px; border-top: 3px solid var(--accent); }
.rt-mark.rt-mark-ac { border-top-color: #000000; }
.rt-mark.dashed { border-top-style: dashed; }
.rt-mark.dotted { border-top-style: dotted; }
.returns-name {
  font-weight: 600;
  font-size: 12px;
  margin: 0 0 calc(8px * var(--vspace));
  line-height: 1.3;
  min-height: 30px;
}
.returns-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  row-gap: calc(5px * var(--vspace));
  column-gap: 10px;
  margin: 0 0 calc(4px * var(--vspace));
}
.returns-list dt { color: #1a1a1a; white-space: nowrap; }
.returns-list dd {
  margin: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  min-width: 0;
}
.returns-link {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--accent);
  font-size: 12px;
  text-decoration: none;
  margin: 2px 0 4px;
}
.returns-link::before { content: "↗"; font-size: 13px; }
.returns-link:hover { text-decoration: underline; }
.returns-narrative {
  font-size: 11px;
  line-height: 1.5;
  margin: 0;
}
.returns-narrative strong { color: var(--accent); font-weight: 600; }

/* ──────────────────────────────────────────────────────────────────────
   Page footer
   ────────────────────────────────────────────────────────────────────── */

.page-footer {
  margin-top: auto;
  /* Aligned with the rest of the page content (60px both sides). */
  padding: 6px 60px 8px;
  border-top: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 9px;            /* much smaller */
  color: #1a1a1a;
  background: white;
}
.footer-logo {
  height: 24px;
  width: auto;
  display: block;
  flex-shrink: 0;
}
/* Vertical | divider between logo and tagline */
.footer-divider {
  width: 1px;
  height: 16px;
  background: #1a1a1a;
  flex-shrink: 0;
  margin: 0 2px;
}
.footer-lede {
  letter-spacing: 0.16em;
  text-transform: uppercase;
  flex: 1;
  font-weight: 600;          /* bolded per spec */
  font-size: 9px;
}
.footer-meta {
  letter-spacing: 0.02em;
  font-weight: 400;
  font-size: 9px;
}
.footer-meta strong { font-weight: 700; }   /* FAIR + fund name bold */
.footer-meta sup { font-size: 7px; vertical-align: super; }

/* ──────────────────────────────────────────────────────────────────────
   Page 2
   ────────────────────────────────────────────────────────────────────── */

/* Small breathing room above the page-2 "Why we prefer" section */
.page-2 .row-why { margin-top: 14px; }
.row-why .col p { font-size: 12px; line-height: 1.55; margin: 0 0 9px; }
.why-tag { font-size: 12px; font-weight: 600; margin: 10px 0 3px; }

.row-diversification {
  margin-top: 12px;
  /* Section title sits across the full width on its own row, then 3
     paired (donut + list) columns below. */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: start;
}
.row-diversification > .section-title { grid-column: 1 / -1; }

/* Each diversification slot pairs a donut + a list as one column unit.
   On desktop they sit side-by-side; on mobile they stack as donut→list,
   which gives the natural interleaved order Rating / Sectors / Geography
   instead of all 3 donuts then all 3 lists. */
.div-pair {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
.donut-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;                /* lets the 1fr column collapse to its track */
}
.donut-visual {
  height: 140px;            /* visual slot height — column layout budget */
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;       /* anchor the HTML tooltip overlay */
  overflow: visible;        /* let tooltip + hover arc bleed past canvas */
}
/* Canvas pixel buffer is 156×156 so the donut (radius 70 set in sheet.js,
   visible diameter 140) has 8px of breathing room each side for the 6px
   hoverOffset segment expansion. The canvas itself bleeds 8px above/below/
   beside the .donut-visual slot — overflow:visible on the parent lets it. */
.donut-col canvas {
  width: 156px !important;
  height: 156px !important;
  margin: -8px;             /* re-centre the visible 140px donut on the slot */
}

/* HTML tooltip overlay rendered by the donut chart's `external` callback.
   Positioned at the cursor coordinates; absolute to .donut-visual so it
   can extend beyond the 140×140 canvas. */
.donut-tip {
  position: absolute;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.8);
  color: #ffffff;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.3;
  white-space: nowrap;
  z-index: 20;
  opacity: 0;
  transition: opacity 0.1s linear;
  transform: translate(-50%, -120%);   /* anchor by bottom-centre */
}

/* Geography column — the map sits as a GHOST OVERLAY: it's
   position:absolute, so it's out of the grid flow entirely. The
   column's track width stays at 1fr and the donuts to its left don't
   shift. The map paints centered within its column, bleeding into the
   adjacent columns' empty horizontal padding (where the 140px donut
   sits centered in a ~235px column = ~47px slack each side). */
.div-pair.pair-geo .donut-visual {
  position: relative;
  overflow: visible;
  width: 100%;
}
.donut-col .geo-map {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 360px;                /* slightly larger — still within "no donut overlap" budget */
  height: 142px;
  pointer-events: auto;
}
.donut-col .geo-map svg { width: 100%; height: 100%; display: block; }
.donut-col .geo-map path.country {
  stroke: #ffffff;
  stroke-width: 0.4px;
}
.donut-caption { margin: 10px 0 0; }
.donut-caption {
  font-family: "Playfair Display", serif;
  font-style: italic;
  font-size: 12px;
  margin: 10px 0 0;
}

.div-list { list-style: none; padding: 0; margin: 0; font-size: 11px; }
.div-list li { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
.div-bullet { width: 2.5px; height: 13px; background: var(--accent); flex-shrink: 0; }
.div-bullet-others { background: #c8c8c8; }
.div-label { flex: 1; color: #1a1a1a; }
.div-pct { font-variant-numeric: tabular-nums; font-size: 11px; }

/* ──────────────────────────────────────────────────────────────────────
   Contact strip
   ────────────────────────────────────────────────────────────────────── */

.contact-strip {
  background: #ececea;
  padding: 20px 28px;
  margin: 16px -60px 0;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: 28px;
  align-items: center;
  border-left: 5px solid var(--brand-red);
}
.contact-cta h3 {
  margin: 0 0 5px;
  font-family: "Playfair Display", serif;
  font-weight: 400;
  font-size: 17px;
}
.contact-cta p {
  margin: 0;
  font-size: 12px;
  color: #1a1a1a;
  font-style: italic;
}
.contact-card { display: flex; align-items: center; gap: 12px; }
.contact-avatar {
  /* Display size kept small (PDF-style portrait crop) but the
     underlying images are ~1000px tall, so even at high-DPR retina
     this stays plenty sharp.
     `aspect-ratio: 1` defends against source JPEGs that aren't perfectly
     square (e.g. a 4:5 portrait crop would otherwise render as an
     oval inside the circular mask). `object-position: center top` keeps
     the subject's head in frame when the source is taller-than-wide. */
  width: 80px;
  height: 80px;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  flex-shrink: 0;
  background: #cfcfcf;
}
/* Per-person crop:
   Mario's source is portrait-orientation with his head in the upper-center;
   "50% 18%" keeps head + shoulders. CH's source has the head at the very
   top — show the absolute top edge so we don't crop his head off. */
.avatar-mario { object-position: 50% 18%; }
.avatar-ch    { object-position: 50% 0%; }
.contact-card .body { display: flex; flex-direction: column; }
.contact-card strong {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: #1a1a1a;
}
.contact-card em {
  font-style: italic;
  font-size: 11px;
  color: #1a1a1a;
  margin-bottom: 2px;
}
.contact-card a {
  font-size: 12px;
  color: #1a1a1a;
  text-decoration: none;
}

/* ──────────────────────────────────────────────────────────────────────
   Responsive
   ────────────────────────────────────────────────────────────────────── */

@media screen and (max-width: 920px) {
  /* Page is flush to viewport edges — kill the desktop card-on-grey look:
     no sheet-wrap top padding, no inter-page gap, no page shadow, no max
     width. The banner now hugs the top of the viewport. */
  body.page-sheet { background: white; }
  .sheet-wrap   { padding: 0; gap: 0; }
  .page         { width: 100%; height: auto; box-shadow: none; }

  /* Horizon strip flush to the top of the banner — no padding above it,
     just like the desktop layout. The 22px below the strip is preserved
     so the FairHorizon label doesn't crash into the fund title. */
  .page-banner { padding: 0 26px 26px; }
  .horizon-strip { margin: 0 -26px 22px; padding: 0 8px; }
  .page-body   { padding: 18px 26px; }

  /* Footer: one-line affair on mobile. Drop the FAIRSHEET™ + page
     marker tail; just the logo + tagline. */
  .page-footer { padding: 10px 26px; gap: 10px; }
  .footer-meta { display: none; }
  .footer-lede { font-size: 9px; }

  .row-about, .row-perf, .row-why, .row-diversification,
  .row-returns, .page-banner-body { grid-template-columns: 1fr; }
  /* The .row-returns-cols-{1,2,3} variants set above are MORE specific
     than the bare `.row-returns` rule, so they'd otherwise leak through
     and force a 3-col layout on mobile, squishing the dt labels into the
     dd percentage values. Re-state at the same 2-class specificity. */
  .row-returns.row-returns-cols-1,
  .row-returns.row-returns-cols-2,
  .row-returns.row-returns-cols-3 { grid-template-columns: 1fr; }
  /* Geography overlay: on mobile the column is full-width so the map's
     fixed 320px width no longer needs to bleed across siblings. Keep it
     centered inside its column. */
  .div-pair.pair-geo .donut-visual { width: auto; }

  /* Contact strip on mobile: CTA spans full width on top; Mario + CH cards
     sit side-by-side in a 2-column row underneath. Bleed flush to the page
     edges (matching the desktop look) by mirroring page-body's 26px gutter
     in negative margin. Button and avatars sized down so nothing clips. */
  .contact-strip {
    margin: 16px -26px 0;
    padding: 18px 20px;
    grid-template-columns: 1fr 1fr;
    gap: 16px 14px;
    align-items: start;
  }
  .contact-cta {
    grid-column: 1 / -1;
  }
  .contact-cta h3 { font-size: 16px; }
  .contact-cta p { font-size: 11.5px; }
  .contact-btn-strip {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 11px 10px;
    font-size: 10.5px;
    letter-spacing: 0.10em;
    text-align: center;
    white-space: normal;
    line-height: 1.25;
  }
  .contact-card { gap: 10px; align-items: center; min-width: 0; }
  .contact-avatar { width: 56px; height: 56px; }
  .contact-card .body { min-width: 0; }
  .contact-card strong { font-size: 11.5px; }
  .contact-card em     { font-size: 10.5px; }
  .contact-card a {
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* Inline link styling for the key-facts dl values (Asset Class → glossary) */
.meta-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
}
.meta-link:hover { border-bottom-style: solid; }

/* ──────────────────────────────────────────────────────────────────────
   Per-fund Contact CTA (inside the contact-strip aside)
   ────────────────────────────────────────────────────────────────────── */
.contact-btn-strip {
  display: inline-block;
  margin-top: 10px;
  padding: 9px 18px;
  background: var(--brand-red);
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 7px;
  box-shadow: 0 2px 4px rgba(var(--brand-red-rgb), 0.18);
  transition: background-color 0.12s;
}
.contact-btn-strip:hover { background: var(--brand-red-hover); }

/* ──────────────────────────────────────────────────────────────────────
   FAQ block (page 2)
   ────────────────────────────────────────────────────────────────────── */
.row-faq { margin-top: 20px; }
.faq-list {
  margin: 6px 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 28px;
}
.faq-item { border-top: 1px solid var(--line); padding-top: 10px; }
.faq-item dt {
  font-weight: 600;
  font-size: 12px;
  color: var(--ink);
  margin-bottom: 4px;
}
.faq-item dd {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ──────────────────────────────────────────────────────────────────────
   Related funds widget
   ────────────────────────────────────────────────────────────────────── */
.row-related { margin-top: 20px; }
.related-grid {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.related-card { display: block; }
.related-card a {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  text-decoration: none;
  color: var(--ink);
  transition: background-color 0.12s;
}
.related-card a:hover { background: var(--accent-soft); }
.related-code {
  font-family: var(--font-mono);
  font-size: 10px; font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.related-name {
  font-size: 12px; font-weight: 600;
  line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.related-class { font-size: 10px; color: var(--ink-soft); }

/* ──────────────────────────────────────────────────────────────────────
   Editorial byline / E-E-A-T signature
   ────────────────────────────────────────────────────────────────────── */
.row-byline { margin-top: 16px; }
.byline {
  margin: 0;
  font-size: 11px;
  color: var(--ink-soft);
  border-top: 1px solid var(--line);
  padding-top: 10px;
  font-style: italic;
}

@media screen and (max-width: 920px) {
  .faq-list { grid-template-columns: 1fr; gap: 12px; }
  .related-grid { grid-template-columns: 1fr 1fr; }
}
@media screen and (max-width: 600px) {
  .related-grid { grid-template-columns: 1fr; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Per-sheet manga-style navigator
   Fixed bottom bar with prev/next arrows + a centre table-of-contents
   button that opens a translucent overlay listing the entire FairSheets
   canon. Keyboard arrows also navigate prev/next.
   ───────────────────────────────────────────────────────────────────────── */
.sheet-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 12px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  pointer-events: none;
  font-family: "Exo 2", "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.sheet-nav > *,
.sheet-nav-right > *,
.sheet-nav-meta > * { pointer-events: auto; }
.sheet-nav-prev { justify-self: start; align-self: end; }
.sheet-nav-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  justify-self: end;
}
.sheet-nav-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.sheet-nav-arrow,
.sheet-nav-toc,
.sheet-nav-exit {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.78);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
          backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.06);
  text-decoration: none;
  color: #1a1a1a;
  font-size: 13px;
  line-height: 1.2;
  transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
}
.sheet-nav-arrow:hover,
.sheet-nav-toc:hover,
.sheet-nav-exit:hover {
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.14), 0 2px 4px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}

.sheet-nav-glyph {
  font-family: "Playfair Display", serif;
  font-size: 22px;
  line-height: 1;
  color: var(--accent, #1a1a1a);
  font-weight: 400;
}

.sheet-nav-exit {
  width: 30px; height: 30px;
  padding: 0;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  color: rgba(26, 26, 26, 0.70);
}
.sheet-nav-exit:hover { color: #1a1a1a; }

.sheet-nav-side {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  max-width: 260px;
}
.sheet-nav-next .sheet-nav-side { justify-content: flex-end; }
.sheet-nav-code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent, #1a1a1a);
}
.sheet-nav-name {
  font-weight: 600;
  font-size: 12px;
  color: #1a1a1a;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  max-width: 200px;
}

.sheet-nav-toc {
  justify-self: center;
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0.10);
  background: rgba(255, 255, 255, 0.86);
  font: inherit;
}
.sheet-nav-toc-count {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: #1a1a1a;
  font-weight: 600;
}
.sheet-nav-toc-icon {
  display: grid;
  grid-template-columns: repeat(3, 4px);
  grid-template-rows:    repeat(2, 4px);
  gap: 2px;
}
.sheet-nav-toc-icon > span {
  display: block;
  width: 4px; height: 4px;
  background: #1a1a1a;
  border-radius: 1px;
}

@media screen and (max-width: 720px) {
  .sheet-nav { padding: 8px 10px calc(8px + env(safe-area-inset-bottom)); gap: 8px; }
  .sheet-nav-side { display: none; }
  .sheet-nav-arrow { padding: 6px 12px; }
  .sheet-nav-glyph { font-size: 20px; }
  .sheet-nav-toc { padding: 5px 10px; gap: 6px; }
  .sheet-nav-exit { width: 28px; height: 28px; }
}

@media print {
  .sheet-nav, .canon-overlay { display: none !important; }
}

/* Translucent canon overlay ─────────────────────────────────────────────── */
.canon-overlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: stretch;
  justify-content: center;
  font-family: "Exo 2", "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.canon-overlay[hidden] { display: none; }
.canon-overlay-scrim {
  position: absolute;
  inset: 0;
  background: rgba(20, 22, 28, 0.52);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
          backdrop-filter: blur(10px) saturate(120%);
  cursor: pointer;
}
.canon-overlay-panel {
  position: relative;
  margin: auto;
  width: min(880px, 96vw);
  max-height: min(86vh, 880px);
  display: flex;
  flex-direction: column;
  background: rgba(252, 250, 246, 0.94);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
          backdrop-filter: blur(20px) saturate(160%);
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.32), 0 4px 12px rgba(0, 0, 0, 0.14);
  overflow: hidden;
  animation: canonPop 0.18s ease-out;
}
@keyframes canonPop {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.canon-overlay-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}
.canon-overlay-title {
  margin: 0;
  font-family: "Playfair Display", serif;
  font-size: 20px;
  font-weight: 500;
  color: #1a1a1a;
}
.canon-overlay-sub {
  margin: 4px 0 0;
  font-size: 12px;
  color: rgba(26, 26, 26, 0.60);
}
.canon-overlay-close {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(0, 0, 0, 0.10);
  width: 32px; height: 32px;
  border-radius: 50%;
  font-size: 20px;
  line-height: 1;
  color: #1a1a1a;
  cursor: pointer;
  transition: background 0.12s;
}
.canon-overlay-close:hover { background: rgba(0, 0, 0, 0.06); }

.canon-overlay-body {
  overflow-y: auto;
  padding: 8px 14px 18px;
  scroll-behavior: smooth;
}

.canon-group { padding: 12px 8px 4px; }
.canon-group-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 6px;
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(26, 26, 26, 0.55);
}
.canon-group-swatch {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--accent, #888);
}
.canon-group-count {
  margin-left: auto;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  color: rgba(26, 26, 26, 0.45);
  letter-spacing: 0.04em;
}

.canon-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 8px;
}
@media screen and (max-width: 700px) { .canon-list { grid-template-columns: 1fr; } }

.canon-row a {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 8px;
  text-decoration: none;
  color: #1a1a1a;
  transition: background 0.10s;
}
.canon-row a:hover { background: var(--accent-soft, rgba(0,0,0,0.05)); }
.canon-code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent, #1a1a1a);
  text-align: center;
}
.canon-name {
  font-size: 12px;
  font-weight: 500;
  color: #1a1a1a;
  line-height: 1.3;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  min-width: 0;
}
.canon-row.is-current a {
  background: var(--accent-soft, rgba(0,0,0,0.06));
  outline: 1.5px solid var(--accent, #1a1a1a);
  outline-offset: -1.5px;
}
.canon-here {
  font-weight: 300;
  font-size: 9px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--accent, #1a1a1a);
  white-space: nowrap;
}

body.canon-open { overflow: hidden; }

/* Site header (.topbar / .brand-logo / .topbar-nav / .topbar-burger /
   .contact-btn / @print hide) — all live in the shared _topbar.css partial.
   This file used to duplicate ~135 lines of those rules; sheet-page-specific
   sizing (compact logo, smaller CTA padding, non-sticky position) is now
   expressed as CSS-variable overrides in _topbar.css under body.page-sheet. */
