/* ==========================================================================
   ADVASA — Base, layout and components
   Every value in this file references a token. No raw values.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. RESET
   Replaces the destyle.css CDN dependency. The previous site loaded its CSS
   reset and its carousel library from jsDelivr, so an outage there stripped
   the site of its layout.
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* The header is position: sticky, so a fragment link scrolls its target to y=0
   and the header then sits on top of it - clicking a portrait on the homepage
   landed with the biography's photograph, name and role hidden. Anchor targets
   reserve the header's height plus a gap, so the element arrives below it.
   1px is the header's bottom border, which sits outside --header-h.
   Applies to any element with an id; scroll-margin has no effect until
   something scrolls to it. */
[id] { scroll-margin-top: calc(var(--header-h) + 1px + var(--s-4)); }
body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1, "liga" 1;
}
/* height:auto is required, not cosmetic. The width/height attributes on <img>
   are presentational hints that set a *definite* height, which causes the
   browser to ignore any aspect-ratio set in CSS. Without this, every portrait
   on the site renders at the attribute's 500px height instead of the crop in
   --ratio-portrait, so the ratio silently varies with column width. */
img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }
:where(h1, h2, h3, h4) { font-weight: var(--fw-regular); text-wrap: balance; }
p { text-wrap: pretty; }

section[tabindex]:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--brand-500);
  outline-offset: 3px;
  border-radius: var(--r-control);
}

.skip-link {
  position: absolute; left: var(--s-3); top: -100px;
  background: var(--brand-800); color: var(--text-inverse);
  padding: var(--s-2) var(--s-3); border-radius: var(--r-control);
  z-index: 200; transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--s-3); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* --------------------------------------------------------------------------
   2. TYPOGRAPHY
   -------------------------------------------------------------------------- */
.display {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  font-weight: var(--fw-regular);
}
.h1, .h2 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
}
.h3 {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
}
.h4 {
  font-family: var(--font-body);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-heading);
}
.lead {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--text-muted);
  max-width: var(--measure);
}
.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--s-3); }
.small { font-size: var(--fs-sm); }
.muted { color: var(--text-muted); }
.tabular { font-variant-numeric: tabular-nums; }

/* Eyebrow — the small tracked-out label above a section heading. Does the
   work the old site was using colour and size jumps for. */
.eyebrow {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-bottom: var(--s-3);
}
.eyebrow::before {
  content: ""; width: 24px; height: 1px;
  background: var(--accent); flex: none;
}
.eyebrow--inverse { color: var(--brand-200); }

/* --------------------------------------------------------------------------
   3. LAYOUT
   -------------------------------------------------------------------------- */
.container {
  width: 100%; max-width: var(--container);
  margin-inline: auto; padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }
.section { padding-block: var(--section-y); }
.section--subtle { background: var(--bg-subtle); }
.section--inverse { background: var(--bg-inverse); color: var(--text-inverse); }
.section--inverse .lead,
.section--inverse .muted { color: var(--brand-100); }

.section-head { margin-bottom: 2rem; }
.grid { display: grid; gap: var(--s-4); }
.divider { height: 1px; background: var(--border); border: 0; }

/* --------------------------------------------------------------------------
   4. HEADER / NAVIGATION
   Five sections, each appearing exactly once. The previous nav had nine
   top-level slots with Board of Directors and Management Team duplicated
   across two of them.
   -------------------------------------------------------------------------- */
.header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}
.header__inner {
  height: var(--header-h);
  display: flex; align-items: center; gap: var(--s-3);
}
@media (min-width: 1024px) { .header__inner { gap: var(--s-5); } }
.brand { display: flex; align-items: center; flex: none; }
/* The adbt.io logo, with its transparent margin removed. The file as served is
   409x105 with 37px of empty space above the letters and 3px below, so the mark
   sits in the bottom 62% of its own canvas — sized or aligned by that canvas it
   never lands where the eye expects. The trimmed copy is 402x65 and is all ink,
   so the height set here is cap height and nothing else.
   `images/logo_orange.png` is kept untouched as the file received from the live
   site. The `Holdings` sub-label was removed on CEO instruction, 12 August 2026;
   the logo now stands alone in both header and footer, and the holding company
   is named in the footer's Entity row on every page. */
.brand__logo { height: 1.125rem; width: auto; display: block; }
/* Smaller in the footer than in the header, and set so its foot lands on the
   baseline of COMPANY, GOVERNANCE and the other column headings across the row.
   Those headings are 13px at a 1.65 line-height, which puts their baseline 17px
   below the top of the grid row; a 15px mark with no offset ends exactly there.
   The 7px lift is deliberate on top of that, on CEO instruction: the mark reads
   as the head of its column rather than as one more item in the heading row.
   Measured against a render, not assumed. Orange on --brand-900, not white. */
.footer__brand .brand__logo { height: 0.9375rem; transform: translateY(-7px); }

.nav { display: none; margin-inline-start: auto; }
.nav__list { display: flex; align-items: center; gap: var(--s-1); }
.nav__link {
  display: block; padding: var(--s-2) var(--s-3);
  font-size: var(--fs-sm); font-weight: var(--fw-medium);
  color: var(--text-muted); border-radius: var(--r-control);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav__link:hover { color: var(--brand-700); background: var(--n-50); }
.nav__link[aria-current="page"] { color: var(--brand-700); }

.nav__group { position: relative; }
.nav__toggle {
  display: flex; align-items: center; gap: var(--s-1);
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-sm); font-weight: var(--fw-medium);
  color: var(--text-muted); border-radius: var(--r-control);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav__toggle:hover,
.nav__group:focus-within .nav__toggle { color: var(--brand-700); background: var(--n-50); }
.nav__toggle svg { transition: transform var(--dur) var(--ease); }
.nav__group:hover .nav__toggle svg,
.nav__group:focus-within .nav__toggle svg { transform: rotate(180deg); }

.nav__menu {
  position: absolute; top: calc(100% + var(--s-2)); left: 0;
  min-width: 260px; padding: var(--s-2);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--r-container); box-shadow: var(--shadow-2);
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              visibility var(--dur);
}
.nav__group:hover .nav__menu,
.nav__group:focus-within .nav__menu {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.nav__menu a {
  display: block; padding: var(--s-2) var(--s-3);
  border-radius: var(--r-control); font-size: var(--fs-sm);
  transition: background var(--dur) var(--ease);
}
.nav__menu a:hover { background: var(--n-50); }
.nav__menu a span {
  display: block; font-size: var(--fs-xs);
  color: var(--text-subtle); margin-top: 2px;
}

.header__actions { display: flex; align-items: center; gap: var(--s-3); margin-inline-start: auto; }
/* Below desktop the Contact CTA lives in the mobile menu, so the header row
   stays narrow enough not to force horizontal overflow. */
.header__actions .btn { display: none; }
@media (min-width: 1024px) { .header__actions .btn { display: inline-flex; } }
.lang {
  display: flex; align-items: center; gap: var(--s-1);
  font-size: var(--fs-xs); color: var(--text-subtle);
  letter-spacing: 0.04em;
}
.lang a[aria-current] { color: var(--brand-700); font-weight: var(--fw-semibold); }
.lang span { color: var(--border-strong); }

@media (min-width: 1024px) {
  .nav { display: block; }
  .header__actions { margin-inline-start: 0; }
}

/* Mobile navigation */
.nav-toggle-btn {
  margin-inline-start: auto; padding: var(--s-2);
  display: flex; flex-direction: column; gap: 4px;
}
.nav-toggle-btn span {
  display: block; width: 22px; height: 1.5px; background: var(--text);
}
.mobile-nav {
  display: none; padding: var(--s-3) 0 var(--s-5);
  border-top: 1px solid var(--border);
}
/* The drawer lives inside a position: sticky header. Left unconstrained it
   makes the header taller than the viewport - 985px of menu against 760px of
   screen - and because the header is pinned at top: 0, scrolling the page never
   brings the lower half into reach. The menu has to scroll within itself.

   dvh rather than vh so the drawer resizes when a mobile browser's address bar
   collapses; vh first as the fallback. overscroll-behavior stops the scroll
   chaining to the page underneath once the menu hits its end. */
.mobile-nav[data-open="true"] {
  display: block;
  /* 1px is the header's own bottom border, which sits outside --header-h. */
  max-height: calc(100vh - var(--header-h) - 1px);
  max-height: calc(100dvh - var(--header-h) - 1px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav h2 {
  font-size: var(--fs-xs); letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--text-subtle);
  margin: var(--s-4) 0 var(--s-2);
}
.mobile-nav a { display: block; padding: var(--s-2) 0; font-size: var(--fs-base); }
@media (min-width: 1024px) {
  .mobile-nav { display: none; }
  .nav-toggle-btn { display: none; }
}

/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */
/* Compact by design. The previous 12px/24px at 15px produced a ~45px control
   that read as a consumer call-to-action; at 8px/18px the button sits at ~34px
   and behaves like a label rather than a target. Chosen 30 July 2026 from a
   four-way comparison. */
.btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 0.5rem 1.125rem;
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  border-radius: var(--r-control);
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
  white-space: nowrap;
}
/* The primary button is the corporate hex itself, with near-black type rather
   than white. White on #ff9317 is 2.2:1 and unreadable; the dark type gives
   8:1 and keeps the button unmistakably the brand colour instead of a
   darkened approximation of it. Hover lightens rather than darkens, so the
   type stays legible through the transition. */
.btn--primary { background: var(--brand-400); color: var(--n-900); }
.btn--primary:hover { background: var(--brand-300); }
.btn--secondary {
  border: 1px solid var(--border-strong); color: var(--text);
  background: var(--bg);
}
.btn--secondary:hover { border-color: var(--brand-600); color: var(--brand-700); }
.btn--ghost { padding-inline: 0; color: var(--brand-700); font-weight: var(--fw-semibold); }
.btn--ghost:hover { color: var(--brand-500); }
.btn--ghost::after {
  content: "→"; transition: transform var(--dur) var(--ease);
}
.btn--ghost:hover::after { transform: translateX(3px); }
.btn--on-dark { background: var(--n-0); color: var(--brand-800); }
.btn--on-dark:hover { background: var(--brand-50); }

/* Outlined button on a dark band. These used to carry the same three
   declarations as inline styles on every instance, which meant nothing could
   override them - including :hover, so they had no hover state at all. */
.section--inverse .btn--secondary {
  background: transparent;
  color: var(--text-inverse);
  border-color: rgba(255, 255, 255, 0.35);
}
.section--inverse .btn--secondary:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.75);
  color: var(--text-inverse);
}

/* --------------------------------------------------------------------------
   6. NEEDS-INPUT MARKER
   Deliberately outside the palette. This must never be mistaken for a design
   element — it marks information ADVASA has to supply before launch.
   Every instance is greppable:  grep -rn "needs-input" site/
   -------------------------------------------------------------------------- */
.needs-input {
  display: inline-flex; align-items: center; gap: 0.4em;
  font-family: var(--font-mono);
  font-size: 0.78em; font-weight: 600;
  line-height: 1.3;
  color: #7a3d00;
  background: repeating-linear-gradient(
    -45deg, #fff2cc, #fff2cc 8px, #ffe9ad 8px, #ffe9ad 16px);
  border: 1.5px dashed #d98b00;
  border-radius: var(--r-control);
  padding: 0.25em 0.6em;
  text-transform: none; letter-spacing: 0;
  vertical-align: middle;
}
.needs-input::before { content: "⚑"; font-size: 1.05em; }

/* Block variant. NOT flex: several of these contain <strong> and <a>, and as
   flex items those were laid out as separate columns instead of flowing as
   text. Block display with an inline marker keeps the sentence intact. */
.needs-input--block {
  display: block; padding: var(--s-3); margin-block: var(--s-2);
  line-height: var(--lh-snug);
}
.needs-input--block::before { margin-right: 0.4em; }

/* Review toggle. Default state is set in _partials/base.html — currently
   hidden, at the client's instruction, with the toggle explained to the CEO
   separately. The markers remain the deliverable: they are hidden, not
   removed, and grep still finds every one of them. */
.flags-off .needs-input { display: none !important; }
/* A section whose only content is markers collapses with them, rather than
   leaving a band of empty page behind. */
.flags-off .section--flags { display: none; }
/* Same idea one level down. A line that exists only to carry a marker - the
   「所在地：」 and 「連絡先：」 rows in the privacy policy - would read as an empty
   field once the marker is hidden, which looks like a fault rather than a gap.
   The label collapses with its marker. */
.flags-off .needs-input-row { display: none; }

.flagtoggle {
  position: fixed; right: var(--s-3); bottom: var(--s-3); z-index: 300;
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  color: var(--text-inverse); background: var(--n-900);
  border-radius: 100px; box-shadow: var(--shadow-2);
  opacity: 0.55; transition: opacity var(--dur) var(--ease);
}
.flagtoggle:hover, .flagtoggle:focus-visible { opacity: 1; }
.flagtoggle__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange-300); flex: none;
}
.flags-off .flagtoggle__dot { background: var(--n-500); }
@media print { .flagtoggle { display: none; } }

/* --------------------------------------------------------------------------
   7. HERO
   Static. No autoplay video, no carousel.
   -------------------------------------------------------------------------- */
/* LIGHT HERO. The hero was previously a full-bleed dark band. It read as heavy —
   the masthead is the first thing an investor sees, and a dark slab competes
   with the serif headline rather than carrying it. Light ground, dark type: the
   register of a bank's annual report rather than a product launch.
   This matters more under the orange palette, not less. A full-bleed #ff9317
   masthead is the single fastest way to make the page read as a promotion, so
   the brand colour arrives here as the wordmark, the chart and the button —
   the marks a reader looks at — rather than as the surface behind them. The
   dark end of the ramp still owns the governance band and the footer. */
.hero {
  position: relative;
  background: var(--bg-subtle);
  color: var(--text);
  padding-block: clamp(var(--s-6), 8vw, var(--s-8));
  overflow: hidden;
}
/* Two washes drifting across the hero panel, enough to stop it reading as flat
   grey and not enough to be seen as a colour. Both were cool — a teal trace
   and a navy one — and on a pale ground they were a large part of why the page
   read as blue. They now carry the brand hue at the same strength.
   The cycle is 26 seconds and the travel is a few percent, so the panel is
   never quite static but the movement is below the threshold of anything you
   would call an animation. Nothing moves under the text. */
.hero::after {
  content: ""; position: absolute; inset: -25%;
  background:
    radial-gradient(ellipse 55% 45% at 72% 22%,
      rgba(255, 147, 23, 0.16), transparent 68%);
  pointer-events: none;
  animation: heroDrift 26s ease-in-out infinite alternate;
}
/* A second wash, larger and slower, travelling the other way. Two layers
   crossing is what makes the movement legible — a single one drifting on a
   pale ground reads as nothing at all. */
.hero::before {
  content: ""; position: absolute; inset: -25%; z-index: 0;
  background:
    radial-gradient(ellipse 60% 50% at 25% 78%,
      rgba(168, 84, 0, 0.13), transparent 70%);
  pointer-events: none;
  animation: heroDriftAlt 34s ease-in-out infinite alternate;
}
@keyframes heroDrift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-9%, 5%, 0) scale(1.18); }
}
@keyframes heroDriftAlt {
  from { transform: translate3d(0, 0, 0) scale(1.06); }
  to   { transform: translate3d(8%, -6%, 0) scale(1); }
}

/* Entrance. Each line arrives a beat after the one above it. Small distances,
   long easing — the effect should register as the page settling, not as motion
   design. */
.hero__tagline,
.hero__title,
.hero__lead,
.hero__actions { animation: heroRise 900ms var(--ease) both; }
.hero__tagline { animation-delay: 60ms; }
.hero__title   { animation-delay: 140ms; }
.hero__lead    { animation-delay: 260ms; }
.hero__actions { animation-delay: 380ms; }

@keyframes heroRise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* Anyone who has asked their system for less motion gets none of it, and gets
   the finished state immediately rather than a delayed fade. */
@media (prefers-reduced-motion: reduce) {
  .hero::after, .hero::before { animation: none; }
  .hero__tagline,
  .hero__title,
  .hero__lead,
  .hero__actions { animation: none; opacity: 1; transform: none; }
  /* The motif holds its completed state: all bars up, payday landed. */
  .hero__bars .bar { animation: none; transform: none; opacity: 1; }
  .hero__pulse     { animation: none; opacity: 0; }
}
.hero__inner { position: relative; z-index: 1; }
/* Copy left, motif right. Single column until there is genuinely room for two;
   below that the motif stacks underneath rather than disappearing. */
@media (min-width: 1024px) {
  .hero__inner {
    display: grid; grid-template-columns: 1fr 0.85fr;
    gap: var(--s-6); align-items: center;
  }
}
/* Visible at every width. It used to be display:none below 1024px, which meant
   it simply did not exist in a narrow preview pane — invisible is worse than
   small. Under 1024px it stacks beneath the copy at a reduced size. */
.hero__figure { display: block; margin-top: var(--s-5); max-width: 380px; }
@media (min-width: 1024px) { .hero__figure { margin-top: 0; max-width: none; } }
.hero__svg { display: block; width: 100%; height: auto; overflow: visible; }

/* ---- Accrual motif -------------------------------------------------------
   Fourteen bars rise in sequence over a 9-second loop, then payday lands and
   the cycle restarts. The stagger is 0.14s, so the whole wave takes about two
   seconds to cross — fast enough to read as movement at a glance, slow enough
   not to nag. Bars scale from their own base, which is why transform-box is
   fill-box rather than the SVG origin. */
.hero__bars .bar {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: barRise 9s var(--ease) infinite;
}
.hero__bars .bar:nth-child(1) { animation-delay: 0.00s; }
.hero__bars .bar:nth-child(2) { animation-delay: 0.14s; }
.hero__bars .bar:nth-child(3) { animation-delay: 0.28s; }
.hero__bars .bar:nth-child(4) { animation-delay: 0.42s; }
.hero__bars .bar:nth-child(5) { animation-delay: 0.56s; }
.hero__bars .bar:nth-child(6) { animation-delay: 0.70s; }
.hero__bars .bar:nth-child(7) { animation-delay: 0.84s; }
.hero__bars .bar:nth-child(8) { animation-delay: 0.98s; }
.hero__bars .bar:nth-child(9) { animation-delay: 1.12s; }
.hero__bars .bar:nth-child(10) { animation-delay: 1.26s; }
.hero__bars .bar:nth-child(11) { animation-delay: 1.40s; }
.hero__bars .bar:nth-child(12) { animation-delay: 1.54s; }
.hero__bars .bar:nth-child(13) { animation-delay: 1.68s; }
.hero__bars .bar:nth-child(14) { animation-delay: 1.82s; }

@keyframes barRise {
  0%          { transform: scaleY(0); opacity: 0; }
  10%         { transform: scaleY(1); opacity: 1; }
  70%         { transform: scaleY(1); opacity: 1; }
  84%         { transform: scaleY(1); opacity: 0; }
  100%        { transform: scaleY(0); opacity: 0; }
}

/* The final bar is payday — near-black against the orange run. */
.bar--payday { fill: var(--brand-900); }
/* Payday ripple. Bars sit 31 units apart, so a ring reaching scale 13.5 from
   r=7 spans about 189 units — a little over six bar widths. Three rings, 0.38s
   apart, so it reads as a ripple rather than one blip. The travel window is
   stretched to match the larger distance, otherwise the rings would simply
   move faster. The SVG allows overflow, so they are free to run past the
   artboard edge. */
.hero__pulse {
  transform-box: view-box; transform-origin: 445px 43px;
  animation: paydayRipple 9s var(--ease) infinite;
}
.hero__pulse--2 { animation-delay: 0.38s; }
.hero__pulse--3 { animation-delay: 0.76s; }

@keyframes paydayRipple {
  0%, 28% { transform: scale(1);    opacity: 0; }
  31%     { transform: scale(1);    opacity: 0.7; }
  64%     { transform: scale(13.5); opacity: 0; }
  100%    { transform: scale(13.5); opacity: 0; }
}


.hero__tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-lg);
  color: var(--accent-text);
  margin-bottom: var(--s-3);
}
.hero__title { max-width: 20ch; margin-bottom: 2rem; }
/* Smaller than the site's default .lead. A large headline over a modest
   standfirst is the proportion listed banks use; matching the two sizes makes
   the whole block read as one undifferentiated paragraph. */
.hero__lead {
  color: var(--text-muted); max-width: 54ch;
  font-size: var(--fs-base); line-height: var(--lh-body);
}
.hero__actions {
  display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-5);
}

/* Governance figures strip beneath the hero. All values derive from content
   already published on the site — no new information. */
.facts {
  position: relative; z-index: 1;
  margin-top: var(--s-6); padding-top: var(--s-5);
  border-top: 1px solid var(--border);
  display: grid; gap: var(--s-4);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 768px) { .facts { grid-template-columns: repeat(4, 1fr); } }
.fact__num {
  font-family: var(--font-display);
  font-size: var(--fs-xl); line-height: 1;
  color: var(--brand-800); font-variant-numeric: tabular-nums;
  margin-bottom: var(--s-1);
}
.fact__label {
  font-size: var(--fs-xs); color: var(--text-subtle);
  letter-spacing: 0.04em; line-height: var(--lh-snug);
}

/* --------------------------------------------------------------------------
   8. CARDS
   -------------------------------------------------------------------------- */
.cards { display: grid; gap: var(--s-4); }
/* One card, full measure. With RWA withheld the business grid holds a single
   card, and a lone card sitting in the left half of a two-column grid reads as
   a hole where something was removed. */
.cards--1 { grid-template-columns: minmax(0, 1fr); }
/* Two-up from the smallest screens rather than stacking. A pair of cards read
   as a pair; stacked, the second is a scroll away and the comparison is lost.
   Padding and type step down so they still breathe at ~170px wide. */
.cards--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
@media (max-width: 559px) {
  .cards--2 .card--feature { padding: var(--s-3); }
  .cards--2 .card--feature .card__index { font-size: var(--fs-lg); margin-bottom: var(--s-2); }
  .cards--2 .card__title { font-size: var(--fs-lg); }
  .cards--2 .card__body { font-size: var(--fs-xs); }
  .cards--2 .card__meta { gap: 4px; }
  .cards--2 .chip { font-size: 11px; padding: 1px 5px; }
}
@media (min-width: 768px)  { .cards--2 { gap: var(--s-4); } }
@media (min-width: 900px)  { .cards--3 { grid-template-columns: repeat(3, 1fr); } }

/* Three- and four-card rows on a phone. Stacked, they cost several screens;
   three abreast at 390px would give each card about 113px, or ten characters a
   line. So the row scrolls sideways instead: each card keeps a readable width
   and the next one peeks in at the edge to show there is more.

   The row bleeds to the screen edges - negative margin plus matching padding -
   so it reads as a rail rather than a clipped box. Snap points stop it drifting
   between cards. */
@media (max-width: 767px) {
  .cards--3,
  .cards--4 {
    grid-auto-flow: column;
    grid-auto-columns: 76%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    /* scroll-snap-align: start snaps a card to the scrollport edge, and the
       scrollport is the padding box - so the browser scrolled the rail by
       exactly the gutter on load and the first card sat flush against the
       screen edge, cancelling the padding above. scroll-padding moves the
       snapport inward so cards snap to the gutter instead. */
    scroll-padding-inline: var(--gutter);
    padding-bottom: var(--s-2);
    scrollbar-width: none;
  }
  .cards--3::-webkit-scrollbar,
  .cards--4::-webkit-scrollbar { display: none; }
  .cards--3 > *,
  .cards--4 > * { scroll-snap-align: start; }
}
@media (min-width: 768px)  { .cards--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cards--4 { grid-template-columns: repeat(4, 1fr); } }

.card {
  display: flex; flex-direction: column;
  padding: var(--s-4);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-container);
  transition: border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
a.card:hover { border-color: var(--brand-300); box-shadow: var(--shadow-2); }
.card__title { margin-bottom: var(--s-2); }
.card__body { color: var(--text-muted); font-size: var(--fs-sm); flex: 1; }
/* auto rather than a fixed margin: the card is a flex column and grid rows
   stretch, so this pins every foot to the bottom of its card and the links line
   up across a row whatever the title or body length. With a fixed margin the
   foot follows the text, and one card wrapping to two lines drops its link
   below its neighbours'. */
.card__foot { margin-top: auto; padding-top: var(--s-4); }
.card__index {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--accent-text); margin-bottom: var(--s-3);
  letter-spacing: 0.08em;
}

/* Feature cards — used where a section carries only two or three cards and the
   default size leaves them looking empty. More air inside, a display-weight
   numeral, and a row of attribute chips so the card has something to say
   below the sentence. */
.card--feature { padding: var(--s-5); }
.card--feature .card__index {
  font-family: var(--font-display); font-size: var(--fs-xl);
  line-height: 1; color: var(--orange-500);
  margin-bottom: var(--s-4); letter-spacing: 0;
}
.card__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-top: var(--s-4);
}

/* Cards on a dark band. Replaces the inline styles that were repeated on every
   dark card; the values are identical, so nothing shifts visually. */
.section--inverse .card {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.14);
}
.section--inverse a.card:hover {
  border-color: rgba(255, 255, 255, 0.30);
  box-shadow: none;
}
.section--inverse .card__title { color: var(--text-inverse); }
.section--inverse .card__body  { color: var(--brand-100); }
.section--inverse .card__index { color: var(--orange-300); }
.section--inverse .chip {
  border-color: rgba(255, 255, 255, 0.24);
  color: var(--brand-100);
}

/* Two-column split: copy beside a figure. Stacks below 900px, figure first on
   desktop only when asked to — default is copy first, which is the reading
   order that matters on a phone. */
.split { display: grid; gap: var(--s-5); align-items: center; }
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1.1fr; gap: var(--s-6); }
  /* When the right column is a stacked pair, align to the top rather than
     centring - the copy should start level with the first diagram. */
  .split:has(.figstack) { align-items: start; }
}

/* Editorial figure. Concept diagrams only — anything carrying data would need
   a source, and nothing on this site has one yet. */
/* Stacked pair of figures - a before and after read top to bottom. */
.figstack { display: grid; gap: var(--s-4); }
.figstack .figure:first-child { margin-top: 0; }

.figure { margin: var(--s-5) 0 0; }
/* Photograph inside a figure, as opposed to a concept diagram. */
.figure__img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--border); border-radius: var(--r-container);
}

/* Lists inside long-form copy. The article reset strips markers, so they are
   restored here rather than site-wide. */
.article ul, .article ol { padding-left: var(--s-4); }
.article ul li { list-style: disc; }
.article ol li { list-style: decimal; }
.article li { margin-top: var(--s-2); padding-left: var(--s-1); }
.article li::marker { color: var(--accent-text); }
.figure__svg {
  display: block; width: 100%; height: auto;
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-container);
  padding: var(--s-3);
}
.section--subtle .figure__svg { background: var(--bg); }
.figure__label {
  font-family: var(--font-body); font-size: 13px;
  letter-spacing: 0.04em;
}
.figure__caption {
  margin-top: var(--s-3);
  font-size: var(--fs-xs); color: var(--text-subtle);
  line-height: var(--lh-snug);
}

/* Governance document list */
.doclist { border-top: 1px solid var(--border); }
.doclist li { border-bottom: 1px solid var(--border); }
.doclist a {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-2);
  transition: background var(--dur) var(--ease), padding-inline-start var(--dur) var(--ease);
}
.doclist a:hover { background: var(--n-50); padding-inline-start: var(--s-3); }
/* On the dark band the text is white, so the light hover wash made the row
   unreadable at the moment of hovering. Lift the row instead of lightening it. */
.section--inverse .doclist a:hover { background: rgba(255, 255, 255, 0.09); }
.section--inverse .doclist,
.section--inverse .doclist li { border-color: rgba(255, 255, 255, 0.14); }
.section--inverse .doclist__type { color: var(--brand-200); }
.doclist__name { flex: 1; font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.doclist__type {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-subtle); letter-spacing: 0.06em;
}

/* --------------------------------------------------------------------------
   9. LEADERSHIP
   -------------------------------------------------------------------------- */
/* The portraits butt directly against each other — no column gap, no radius —
   so the row reads as one continuous band rather than five separate cards.
   Removing the gaps also hands their width back to the images, which is the
   point: at five across the columns go from ~200px to ~240px. Row gap is kept
   for the wrapped case on narrow screens. */
.people {
  display: grid; column-gap: 0; row-gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
/* On a phone the 13/25 crop is tall, so two columns produced three rows and
   roughly three screens of scrolling. Three columns makes each portrait
   narrower and therefore shorter - five people fit in two rows, and the crop,
   the flush columns and the square corners are all untouched. */
.person__photo {
  aspect-ratio: var(--ratio-portrait); width: 100%;
  object-fit: cover; object-position: center top;
  border-radius: 0;
  background: var(--n-100);
  filter: grayscale(100%) contrast(1.03);
  transition: filter var(--dur) var(--ease);
  margin-bottom: var(--s-3);
}
.person:hover .person__photo { filter: grayscale(0%); }
.person__name { font-weight: var(--fw-semibold); font-size: var(--fs-base); }
.person__role {
  font-size: var(--fs-xs); color: var(--text-subtle);
  margin-top: 2px; line-height: var(--lh-snug);
}
/* Flex column + auto margin keeps the independence tags on a common baseline
   even when a name wraps to two lines. */
.person { display: flex; flex-direction: column; }
/* With the photographs flush, the captions would otherwise run into the name
   of the person in the next column. The images stay edge to edge; only the
   text is inset. */
.person > :not(.person__photo) { padding-right: var(--s-4); }
/* On the homepage each portrait links to that person's biography. The whole
   cell is the target, photograph included - that is what a reader aims at, and
   a 119px-wide name is a poor hit area. The locked photo treatment is untouched:
   ratio, crop and the flush row are unchanged, and only opacity moves on hover. */
a.person { color: inherit; text-decoration: none; }
a.person .person__name {
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: text-decoration-color 160ms ease;
}
a.person .person__photo { transition: opacity 160ms ease; }
a.person:hover .person__name,
a.person:focus-visible .person__name { text-decoration-color: currentColor; }
a.person:hover .person__photo { opacity: 0.9; }
a.person:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  a.person .person__name, a.person .person__photo { transition: none; }
}
.person__tag {
  display: inline-block; align-self: start;
  margin-top: auto; padding-top: var(--s-2);
  font-size: var(--fs-xs); color: var(--orange-600);
  border: 1px solid var(--orange-200); background: var(--orange-100);
  border-radius: var(--r-control); padding: 1px 6px;
}

/* Phones. The 13/25 crop is tall, so two columns gave three rows and about
   three screens of scrolling. Three columns makes each portrait narrower and
   therefore shorter: five people in two rows. The crop, the flush columns and
   the square corners are untouched.

   Placed after the base .person rules deliberately - these overrides have the
   same specificity, so they only win by coming later.

   minmax(0, 1fr), not 1fr: a bare 1fr floors at min-content, so the columns
   holding the longest names grew and squeezed the third portrait narrower. */
@media (max-width: 559px) {
  .people { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: var(--s-4); }
  .person__name { font-size: var(--fs-xs); line-height: var(--lh-snug); }
  .person__role { font-size: 11px; line-height: 1.35; }
  .person > :not(.person__photo) { padding-right: var(--s-2); }
}

/* --------------------------------------------------------------------------
   10. NEWS
   -------------------------------------------------------------------------- */
/* News filter. Reads as a set of quiet toggles, not primary buttons - the list
   below it is the content. */
.filterbar {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-bottom: var(--s-4);
}
.filterbtn {
  padding: 0.3em 0.85em;
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  color: var(--text-muted);
  border: 1px solid var(--border-strong); border-radius: 100px;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.filterbtn:hover { border-color: var(--brand-400); color: var(--brand-700); }
.filterbtn[aria-pressed="true"] {
  background: var(--brand-700); border-color: var(--brand-700);
  color: var(--text-inverse);
}

.newsrow { border-top: 1px solid var(--border); }
.newsrow li { border-bottom: 1px solid var(--border); }
.newsrow a {
  display: grid; gap: var(--s-1);
  padding: var(--s-4) var(--s-2);
  transition: background var(--dur) var(--ease);
}
@media (min-width: 768px) {
  .newsrow a {
    grid-template-columns: 130px 1fr auto;
    align-items: baseline; gap: var(--s-4);
  }
}
.newsrow a:hover { background: var(--n-50); }
.newsrow time {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--text-subtle); font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
.newsrow__title { font-weight: var(--fw-medium); }

/* --------------------------------------------------------------------------
   11. FOOTER
   -------------------------------------------------------------------------- */
.footer {
  /* Tracks the brand palette so dark surfaces stay coherent when it changes. */
  background: var(--brand-900); color: var(--brand-200);
  padding-block: var(--s-6) var(--s-4);
  font-size: var(--fs-sm);
}
.footer__grid {
  display: grid; gap: var(--s-5);
  grid-template-columns: 1fr;
  padding-bottom: var(--s-5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
@media (min-width: 640px)  { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .footer__grid { grid-template-columns: 1.4fr repeat(4, 1fr); } }
.footer h2 {
  font-size: var(--fs-xs); letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase; color: var(--n-0);
  margin-bottom: var(--s-3); font-weight: var(--fw-semibold);
}
.footer li + li { margin-top: var(--s-2); }
.footer a { color: var(--brand-200); transition: color var(--dur) var(--ease); }
.footer a:hover { color: var(--n-0); }
.footer__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-4);
  justify-content: space-between; align-items: center;
  padding-top: var(--s-4); font-size: var(--fs-xs); color: var(--brand-400);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.footer__disclaimer a { text-decoration: underline; text-underline-offset: 2px; }
.footer__disclaimer a:hover { color: var(--n-0); }
.footer__disclaimer {
  margin-top: var(--s-4); padding-top: var(--s-4);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: var(--fs-xs); color: var(--brand-400);
  max-width: 90ch; line-height: var(--lh-snug);
}

/* Corporate data table in footer */
.corpdata { font-size: var(--fs-xs); line-height: var(--lh-snug); }
.corpdata div { display: flex; gap: var(--s-2); margin-top: var(--s-2); }
.corpdata dt { color: var(--brand-400); flex: none; min-width: 84px; }
.corpdata dd { color: var(--brand-200); }

/* ==========================================================================
   12. INTERIOR PAGE COMPONENTS
   Required by the remaining pages; not exercised by the homepage.
   ========================================================================== */

/* Page header — every interior page opens with this. */
.page-head {
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
  padding-block: var(--s-6) var(--s-5);
}
.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  font-size: var(--fs-xs); color: var(--text-subtle); margin-bottom: var(--s-3);
}
.breadcrumb li::after { content: "/"; margin-inline-start: var(--s-2); color: var(--border-strong); }
.breadcrumb li:last-child::after { content: none; }
.breadcrumb a:hover { color: var(--brand-600); }
/* 22ch was set for short page titles - "Careers.", "Board of Directors." - and
   is far too tight for a news headline: it held "Board adopts ten governance
   documents and constitutes three committees." to four lines in a 430px column
   with 1000px of empty space beside it. In Japanese the same cap is about
   11 full-width characters, which broke 「ガバナン/ス規程」 mid-word and split
   「3/つの」 from its counter.

   text-wrap: balance evens the lines rather than filling each one to the measure
   and leaving a short last line. */
.page-head__title { max-width: 30ch; text-wrap: balance; }
/* ch is the width of "0", a half-width glyph, so a Latin cap under-measures CJK
   by roughly half. em is one full-width character. */
html[lang="ja"] .page-head__title { max-width: 22em; }
/* Body size, not .lead's 21px. These standfirsts sit directly under a large
   serif title, and matching them to the title's weight made the two compete.
   Same correction already applied to the hero lead and the CEO message. */
/* Status line under a page title - a chip plus one sentence of plain fact. */
.page-head__status {
  display: flex; align-items: baseline; gap: var(--s-3);
  flex-wrap: wrap; margin-top: var(--s-3);
  max-width: 62ch; font-size: var(--fs-base);
  line-height: var(--lh-body); color: var(--text-muted);
}
.page-head__status .chip { flex: none; align-self: center; }

.page-head__lead {
  margin-top: var(--s-3); max-width: 62ch;
  font-size: var(--fs-base); line-height: var(--lh-body);
}

/* Long-form article — CEO message, philosophy, news, policy text. */
.article { max-width: var(--measure); font-size: var(--fs-base); }
.article > * + * { margin-top: var(--s-3); }
.article h2 {
  font-family: var(--font-display); font-size: var(--fs-xl);
  line-height: var(--lh-heading); letter-spacing: var(--ls-heading);
  margin-top: var(--s-5);
}
.article h3 {
  font-size: var(--fs-lg); font-weight: var(--fw-semibold);
  margin-top: var(--s-4);
}
.article ul { list-style: disc; padding-inline-start: 1.2em; }
.article li + li { margin-top: var(--s-2); }
.article strong { font-weight: var(--fw-semibold); }
.article a { color: var(--brand-600); text-decoration: underline; text-underline-offset: 2px; }
.article a.btn { text-decoration: none; }

.pullquote {
  border-inline-start: 2px solid var(--accent);
  padding-inline-start: var(--s-4);
  margin-block: var(--s-5);
  font-family: var(--font-display);
  font-size: var(--fs-lg); line-height: var(--lh-snug);
  color: var(--text);
}
.signature { margin-top: var(--s-5); }
.signature__name { font-weight: var(--fw-semibold); }
.signature__role { font-size: var(--fs-sm); color: var(--text-subtle); }

/* Director / officer bio — photo beside long-form text. */
.bio { display: grid; gap: var(--s-4); padding-block: var(--s-6); }
.bio + .bio { border-top: 1px solid var(--border); }
@media (min-width: 768px) {
  .bio { grid-template-columns: 260px 1fr; gap: var(--s-6); align-items: start; }
}

/* Phones. A full-width portrait at the 13/25 crop is about 690px tall - most of
   a screen for one person. The photo becomes a 96px thumbnail with the name
   beside it, and the biography runs full width underneath.

   display: contents lifts the inner wrapper out of the way so name, role, meta
   and body can be placed on the parent grid directly. */
@media (max-width: 767px) {
  .bio {
    grid-template-columns: 96px 1fr;
    column-gap: var(--s-3); row-gap: var(--s-2);
    align-items: start; padding-block: var(--s-5);
  }
  .bio > div { display: contents; }
  .bio__photo { grid-column: 1; grid-row: 1 / span 3; align-self: start; }
  .bio__name  { grid-column: 2; grid-row: 1; font-size: var(--fs-lg); }
  .bio__role  { grid-column: 2; grid-row: 2; }
  /* The rule under .bio__meta separates it from the biography on desktop. On a
     phone the meta sits in the narrow right column, so the rule spanned only
     part of the width and read as a stray line. */
  .bio__meta  { grid-column: 2; grid-row: 3; border-bottom: 0; padding-bottom: 0; }
  .bio__body  { grid-column: 1 / -1; margin-top: var(--s-3); }
}
.bio__photo {
  width: 100%; aspect-ratio: var(--ratio-portrait); object-fit: cover; object-position: center top;
  border-radius: var(--r-container); filter: grayscale(100%) contrast(1.03);
  background: var(--n-100);
}
/* Native <details>, not a modal - see the commit message. The summary is the
   control on phones and is removed entirely above 768px, where every biography
   is open and there is nothing to disclose. */
.bio__more {
  display: none; cursor: pointer; list-style: none;
  margin-top: var(--s-3); padding: 0.35em 0.9em;
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  color: var(--brand-700);
  border: 1px solid var(--border-strong); border-radius: 100px;
  width: fit-content;
}
.bio__more::-webkit-details-marker { display: none; }
.bio__more::after { content: " +"; }
[open] > .bio__more::after { content: " \2212"; }
@media (max-width: 767px) { .bio__more { display: block; } }

.bio__name { font-family: var(--font-display); font-size: var(--fs-xl); line-height: var(--lh-heading); }
.bio__role { color: var(--text-subtle); font-size: var(--fs-sm); margin-top: var(--s-1); }
.bio__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  margin-top: var(--s-3); padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
}
.chip {
  font-size: var(--fs-xs); border: 1px solid var(--border);
  border-radius: var(--r-control); padding: 2px 8px; color: var(--text-muted);
}
.chip--accent { border-color: var(--orange-200); background: var(--orange-100); color: var(--orange-600); }
.bio__body { margin-top: var(--s-3); }
.bio__body > * + * { margin-top: var(--s-3); }

/* Data table — corporate profile, committee composition. */
.datatable { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
/* Default: a caption is the table's title and sits above it. */
.datatable caption {
  text-align: left; margin-bottom: var(--s-3);
  color: var(--text-subtle); font-size: var(--fs-xs);
}

/* .datatable--notes: the caption is a footnote rather than a title, so it moves
   below the table and joins any .datatable-note paragraphs after it.

   caption-side: bottom is used rather than deleting the <caption> element,
   because that element is what names the table for assistive technology.

   The asterisk is positioned rather than typed into the copy, so the sentence
   starts at the same x as the first column's text and wrapped lines align under
   it, not under the marker. No max-width - these run the full table width and
   sit on one line on a desktop. */
.datatable--notes caption,
.datatable-note {
  position: relative; text-align: left;
  padding-left: var(--s-3);
  font-size: var(--fs-xs); color: var(--text-subtle);
  line-height: var(--lh-snug);
}
.datatable--notes caption { caption-side: bottom; margin: var(--s-3) 0 0; }
.datatable-note { margin-top: var(--s-2); }
.datatable--notes caption::before,
.datatable-note::before { content: "*"; position: absolute; left: 4px; }
.datatable th, .datatable td {
  text-align: left; padding: var(--s-3) var(--s-3);
  border-bottom: 1px solid var(--border); vertical-align: top;
}
.datatable thead th {
  font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow); color: var(--text-subtle);
  font-weight: var(--fw-semibold); border-bottom-color: var(--border-strong);
}
.datatable tbody th {
  font-weight: var(--fw-medium); color: var(--text-muted);
  width: 30%; min-width: 160px;
}
.datatable td { font-variant-numeric: tabular-nums; }
.datatable--scroll { overflow-x: auto; }
.tick { color: var(--brand-600); font-weight: var(--fw-semibold); }

/* Forms — contact page. */
.field { display: grid; gap: var(--s-2); margin-bottom: 2rem; }
.label { font-size: var(--fs-sm); font-weight: var(--fw-medium); }
.label .req { color: var(--orange-600); margin-inline-start: 2px; }
.input, .textarea, .select {
  width: 100%; padding: 0.7rem var(--s-3);
  border: 1px solid var(--border-strong); border-radius: var(--r-control);
  background: var(--bg); font-size: var(--fs-base);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.input:focus, .textarea:focus, .select:focus {
  outline: none; border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(217, 116, 0, 0.16);
}
.textarea { min-height: 150px; resize: vertical; }
.hint { font-size: var(--fs-xs); color: var(--text-subtle); }
.form-grid { display: grid; gap: 0 var(--s-4); }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }

/* Submission feedback, pinned just under the sticky header rather than left
   inline: the form is long enough that the submit button is often off screen by
   the time the reply lands, and on a phone it is the whole viewport.
   Always rendered, never display: none — the live region has to be in the
   accessibility tree before its text changes for the change to be announced.
   Nothing inside is focusable, so it cannot become an invisible tab stop. */
.toast {
  position: fixed;
  /* 1px is the header's own bottom border, which sits outside --header-h. */
  top: calc(var(--header-h) + 1px + var(--s-3));
  left: 50%;
  z-index: 160;   /* over the sticky header (100), under the skip link (200) */
  width: calc(100% - var(--s-3) * 2);
  max-width: 30rem;
  padding: var(--s-3);
  border: 1px solid var(--border);
  border-radius: var(--r-control);
  background: var(--bg);
  box-shadow: 0 6px 24px rgba(26, 23, 21, 0.14);
  font-size: var(--fs-sm);
  text-align: center;
  opacity: 0;
  transform: translate(-50%, -6px);
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;   /* so the fallback address can be selected and copied */
}
.toast--ok {
  border-color: var(--brand-200); background: var(--brand-50); color: var(--brand-700);
}
.toast--error {
  border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger-text);
}
@media (prefers-reduced-motion: reduce) {
  .toast { transition: none; transform: translate(-50%, 0); }
}

.btn[aria-busy="true"] { opacity: 0.6; pointer-events: none; }

/* ==========================================================================
   13. GOVERNANCE PAGE COMPONENTS
   ========================================================================== */

/* Figures strip on a light background (the hero variant is white-on-dark). */
.facts--light {
  margin-top: 0; padding-top: var(--s-4);
  border-top-color: var(--border);
}
.facts--light .fact__num { color: var(--text); }
.facts--light .fact__label { color: var(--text-subtle); }

/* Chair is stated in words. The live site distinguishes chair from member
   using two near-identical grey person icons with no visible legend. */
.role-chair {
  display: inline-block;
  font-weight: var(--fw-semibold);
  color: var(--orange-600);
}
.role-chair::before {
  content: ""; display: inline-block;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent);
  margin-inline-end: 7px; vertical-align: 2px;
}

.datatable th a {
  font-weight: var(--fw-semibold); color: var(--text);
  text-decoration: underline; text-underline-offset: 2px;
  text-decoration-color: var(--border-strong);
}
.datatable th a:hover { color: var(--brand-600); text-decoration-color: currentColor; }
.datatable tbody th { width: 34%; }

/* Document list entries carry a one-line description. */
.doclist a { align-items: start; padding-block: var(--s-4); }
.doclist__name { display: block; }
.doclist__desc {
  display: block; margin-top: 4px;
  font-size: var(--fs-sm); font-weight: var(--fw-regular);
  color: var(--text-muted); max-width: 68ch;
}
.doclist__type { flex: none; padding-top: 2px; }

/* ==========================================================================
   14. COMPANY PAGE COMPONENTS
   ========================================================================== */

/* Numbered principles — Philosophy. */
.principles { display: grid; gap: var(--s-5); counter-reset: p; }
.principle {
  display: grid; gap: var(--s-3);
  padding-top: var(--s-4); border-top: 1px solid var(--border);
}
@media (min-width: 768px) {
  .principle { grid-template-columns: 80px 1fr; gap: var(--s-5); }
}
.principle__num {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--accent-text); letter-spacing: 0.1em; padding-top: 6px;
}
.principle__title { margin-bottom: var(--s-3); max-width: 30ch; }
.principle__body { color: var(--text-muted); max-width: var(--measure); }
.principle__body + .principle__body { margin-top: var(--s-3); }

/* CEO message masthead. */
/* Two columns at every width. Left as one column on a phone, the portrait ran
   the full page width and stood about 690px tall. */
.ceo-intro {
  display: grid; grid-template-columns: 104px 1fr;
  gap: var(--s-4); align-items: center;
}
@media (min-width: 640px) {
  .ceo-intro { grid-template-columns: 150px 1fr; gap: var(--s-5); }
}
.ceo-intro__photo {
  width: 100%; aspect-ratio: var(--ratio-portrait); object-fit: cover; object-position: center top;
  border-radius: var(--r-container); filter: grayscale(100%) contrast(1.03);
  background: var(--n-100);
}

/* Corporate profile uses a label/value layout rather than column headers. */
.datatable--profile tbody th {
  width: 32%; min-width: 190px;
  color: var(--text-subtle); font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
}
.datatable--profile td { font-variant-numeric: normal; }
.datatable--profile a {
  color: var(--brand-600); text-decoration: underline; text-underline-offset: 2px;
}

/* ==========================================================================
   15. PATENT CERTIFICATES
   Business overview. Four grant certificates, shown as thumbnails that open
   full size. Nothing here touches .person or .people — the leadership photo
   treatment is locked and these are documents, not portraits.
   ========================================================================== */
.certs {
  display: grid; gap: var(--s-4);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 900px) { .certs { grid-template-columns: repeat(4, 1fr); } }

/* An anchor, not a button: with JavaScript off the href opens the full image
   on its own, so the certificate is never unreachable. */
.cert { display: flex; flex-direction: column; gap: var(--s-3); }
.cert__img {
  display: block; width: 100%;
  aspect-ratio: 1 / 1.32; object-fit: cover; object-position: center top;
  background: var(--n-100);
  border: 1px solid var(--border);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.cert:hover .cert__img { border-color: var(--accent); transform: translateY(-2px); }
.cert:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.cert__place {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.06em; color: var(--accent-text);
}
.cert__no { font-size: var(--fs-sm); font-weight: var(--fw-medium); margin-top: var(--s-1); }
.cert__date { font-size: var(--fs-xs); color: var(--text-subtle); margin-top: 2px; }
/* A .cert__zoom rule lived here for a per-card "Read certificate" label. The
   label was removed on CEO instruction — the line above the grid says it once —
   so the rule went with it rather than being left to rot. */

/* Expanded view. Hidden until opened, so it costs nothing on load: the full
   image has no src until the thumbnail is clicked. */
.lightbox {
  /* Above the sticky header (100), below the skip link (200) and the
     review-only flag toggle (300) so both stay reachable while it is open. */
  position: fixed; inset: 0; z-index: 150;
  display: none; place-items: center;
  padding: var(--s-4);
  background: rgba(26, 23, 21, 0.92);
}
.lightbox[data-open="true"] { display: grid; }
.lightbox__img {
  display: block; max-width: min(920px, 100%); max-height: calc(100vh - 8rem);
  width: auto; height: auto; background: var(--n-0);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}
.lightbox__cap {
  margin-top: var(--s-3); text-align: center;
  font-size: var(--fs-xs); color: var(--n-300);
}
.lightbox__close {
  position: absolute; top: var(--s-3); right: var(--s-3);
  display: grid; place-items: center;
  width: 44px; height: 44px;
  font-size: 22px; line-height: 1;
  color: var(--n-0); background: rgba(255, 255, 255, 0.12);
  border-radius: var(--r-control);
}
.lightbox__close:hover { background: rgba(255, 255, 255, 0.22); }

/* ==========================================================================
   JAPANESE TYPOGRAPHY
   Applied by the document's lang attribute, so the English site is untouched.
   Google Fonts serves CJK in unicode-range subsets, so an English visitor never
   downloads these files.
   ========================================================================== */
html[lang="ja"] body { font-family: var(--font-jp); line-height: 1.85; }

/* Headings, set to match goldmansachs.com/japan: Noto Serif JP at weight 300.
   Their own site reserves the mincho for the hero and sets section headings in
   Noto Sans JP, but the instruction here is one face across every heading.

   Sizes are fixed rather than fluid, and taken from Goldman's own scale
   (36 / 30 / 22). Our Latin scale runs to 46px for a section heading, which
   would leave the 36px hero smaller than the headings beneath it. */
html[lang="ja"] .display:not(.latin),
html[lang="ja"] .h1:not(.latin),
html[lang="ja"] .h2:not(.latin),
html[lang="ja"] .h3:not(.latin),
html[lang="ja"] .article h2:not(.latin),
html[lang="ja"] .pullquote:not(.latin),
html[lang="ja"] .principle__title:not(.latin),
html[lang="ja"] .bio__name:not(.latin) {
  font-family: var(--font-jp-display);
  font-weight: 300;
  letter-spacing: 0;
}

html[lang="ja"] .display:not(.latin) { font-size: 36px; line-height: 1; }
html[lang="ja"] .h1:not(.latin),
html[lang="ja"] .h2:not(.latin),
html[lang="ja"] .article h2:not(.latin) { font-size: 30px; line-height: 1.4; }
html[lang="ja"] .h3:not(.latin),
html[lang="ja"] .bio__name:not(.latin),
html[lang="ja"] .principle__title:not(.latin) { font-size: 22px; line-height: 1.5; }

/* The Latin measure cap is 30ch, and ch is the width of "0" - a half-width
   glyph - so it only admits about 15 full-width Japanese characters. Titles of
   17 and 18 wrapped while the 15-character one did not. In CJK 1em is one
   full-width character, so em caps the measure in the unit the text is
   actually set in. */
html[lang="ja"] .principle__title:not(.latin) { max-width: 26em; }

/* Below about 24px a 300-weight mincho goes thin and loses colour against the
   body text, so the smaller headings take the regular weight instead. */
html[lang="ja"] .h3:not(.latin),
html[lang="ja"] .bio__name:not(.latin),
html[lang="ja"] .principle__title:not(.latin),
html[lang="ja"] .pullquote:not(.latin) { font-weight: 400; }

/* A Latin run inside a Japanese page - a person's name, a company name, a job
   title - is not Japanese text and must not take the Japanese heading rules.
   Those rules change the face AND the size, so without this the same line reads
   differently between the English page and its Japanese twin, most visibly on a
   phone where the Japanese step drops to 24px. Marking it .latin lets it fall
   through to the English rules in full: face, size, leading and tracking. */

/* Card titles stay in the gothic. They are short labels at 21px, not headings
   read as prose, and Goldman sets the same elements in Noto Sans JP. */
html[lang="ja"] .h4,
html[lang="ja"] .card__title { font-family: var(--font-jp); }

/* The wordmark stays in the Latin serif - it is a logo, not text. */

@media (max-width: 559px) {
  html[lang="ja"] .display:not(.latin) { font-size: 28px; line-height: 1.2; }
  html[lang="ja"] .h1:not(.latin),
  html[lang="ja"] .h2:not(.latin),
  html[lang="ja"] .article h2:not(.latin) { font-size: 24px; }
}

/* Japanese has no inter-word space, so a browser may break a line anywhere at
   all - including mid-phrase, which reads as a stumble. Wrapping each clause in
   .phrase makes the clause boundaries the only break points the browser
   prefers, while still letting a long clause wrap inside itself on a narrow
   screen. line-break: strict applies full kinsoku, so a small kana or a closing
   bracket never starts a line. */
/* Full kinsoku: a small kana, a closing bracket or a full stop never starts a
   line. Not overflow-wrap: anywhere - that breaks Latin names mid-word, which
   is how "Witherspoo / n" happened once already. CJK wraps between any two
   characters by default, so nothing extra is needed for the Japanese itself. */
html[lang="ja"] { line-break: strict; }
.phrase { display: inline-block; }
/* One clause per line, for headings written to be read as separate lines. A
   clause still wraps inside itself if the screen is too narrow for it. */
.phrase--line { display: block; }

/* Footer social icon (X): above the brand logo */
.footer a.footer__social { display: inline-flex; align-items: center; margin-bottom: 2rem; color: var(--n-0); }
.footer a.footer__social:hover { color: var(--n-0); opacity: 0.8; }
.footer__social svg { display: block; width: 32px; height: 32px; }
