/* ==========================================================================
   MTech Engineering — ABOUT section layer (light)                  about3d.css
   --------------------------------------------------------------------------
   The About family (Message from the CEO, and the pages that follow it) is on
   the SAME design system as the home and service pages: same type scale, same
   spacing rhythm, same HUD, same section head, checks list, card matrix,
   standard chips, related cards, CTA band, buttons and footer. It layers on
   top of home3d.css exactly the way service3d.css layers on it.

   The theme is the site's standard light theme. Two scenes stand behind these
   pages, both in the same daylight: the executive desk where the letter is
   signed (about3d.js, the Message from the CEO page) and the discipline model
   of a building, one system lit at a time (aboutfirm3d.js, the firm overview).
   Either way the canvas reads as part of the page rather than an inset.

   Ownership: a component that more than one page family renders belongs to
   home3d.css (section 11) — the card matrix, standards strip, related list and
   four-column facts strip are all there, not here. This file owns only what is
   scoped to body.hx-abt, so an About page never has to know which family sheet
   happened to declare a shared component first.

   What this file adds — the only pieces that are not shared furniture:
     · the hero letter: the CEO's portrait, salutation, message and signature
     · the studio plate: the story and the four points, two columns wide
     · the scroll-focus plate: on the live-model page a plate's opacity answers
       how far its middle is from the middle of the window, so the copy being
       read is solid and the copy on its way out lets the model through (§5)
   Everything else on the page is home3d.css — including .hx-plate, the paper
   surface every block of body copy sits on (the About pages are read over a
   lit render, and unplated prose on that render is a contrast problem).

   Depends: assets/css/main.css, home3d.css      Scope: body.hx-abt
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. PLATE
   -------------------------------------------------------------------------- */
.hx.hx-abt { background: var(--hx-bg); }
/* the canvas plate: the same paper white the page sits on */
.hx.hx-abt #gl { background: var(--hx-bg); }

/* --------------------------------------------------------------------------
   2. HERO — the message, and the man who signed it, at the top of the page
   The type stack keeps the home hero's measure (the shared 1.15fr / 0.85fr
   copy grid, so the headline and the lead are the same width here as on every
   other 3D page); the letter plate below it spans BOTH columns, i.e. the full
   container — the block a visitor reads first lines up with the commitments
   matrix and every other section instead of floating in a narrow right column.
   -------------------------------------------------------------------------- */
/* The hero is a header, not a screen: it holds the headline, the lead and the
   letter, and then it gets out of the way. Capped so a 1440x900 visitor sees
   the signed letter inside the fold and the studio section immediately after,
   instead of a full viewport of sky between the two. */
.hx-abt .hx-hero { min-height: min(78svh, 700px); }
.hx-abt .hx-hero__inner { padding-bottom: clamp(18px, 3vh, 34px); }
/* the About-family hero veil that used to run top-down (92% white at the top,
   down to 12% at the foot) is retired with the shared one: this family's copy
   is haloed like every other hero, and the scene reads whole. */
.hx-abt .abt-letter {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 212px minmax(0, 1fr) minmax(190px, 246px);
  gap: clamp(18px, 2.2vw, 34px);
  align-items: start;
  /* the whole letter has to clear the fold on a 1440x900 screen: the margin,
     padding and quote size below are tuned to that, and the signature is the
     last thing you should be able to read without scrolling */
  margin-top: clamp(12px, 1.4vw, 17px);
  padding: clamp(12px, 1.4vw, 17px);
  background: var(--hx-panel);
  border: 1px solid var(--hx-line);
  border-radius: var(--hx-r);
  box-shadow: var(--hx-shadow);
  backdrop-filter: blur(6px);
}
.hx-abt .abt-letter__body { min-width: 0; }
.hx-abt .abt-letter__salute {
  margin: 0 0 12px;
  font-family: var(--hx-mono);
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hx-dim);
}
/* the quote keeps a readable measure: the plate is a third of a screen wider
   than the column this text used to sit in, and a 110-character line is not a
   letter, it is a ticker */
.hx-abt .abt-letter .abt-quote { font-size: clamp(1.05rem, 1.22vw, 1.12rem); line-height: 1.55; max-width: 70ch; }
.hx-abt .abt-letter .abt-quote::before { width: 42px; height: 2px; margin-bottom: 14px; }
.hx-abt .abt-letter .abt-portrait { padding: 6px; box-shadow: none; }
.hx-abt .abt-letter .abt-portrait figcaption { padding: 8px 2px 0; }
/* the signature owns the third column of the plate: on letterhead the name
   sits beside the body, not under it, and it gives the wide plate a right edge */
.hx-abt .abt-letter__sig {
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  padding: 0 0 0 clamp(18px, 2vw, 30px);
  border-top: 0;
  border-left: 1px solid var(--hx-line);
}
.hx-abt .abt-letter__sig .abt-sig__rule { flex: none; width: 100%; }

/* --------------------------------------------------------------------------
   2b. TITLE BLOCK — the studio overview's hero artifact
   The CEO page's hero carries a signed letter; this page carries the block a
   drawing set is identified by. Same plate, same span (both columns of the
   copy grid, i.e. the full container), different artifact — a ruled key/value
   block on the left and the firm's position on the right.
   -------------------------------------------------------------------------- */
.hx-abt .abt-tblock {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  gap: clamp(18px, 2.2vw, 34px);
  align-items: center;
  margin-top: clamp(12px, 1.4vw, 17px);
  padding: clamp(12px, 1.4vw, 17px);
  background: var(--hx-panel);
  border: 1px solid var(--hx-line);
  border-radius: var(--hx-r);
  box-shadow: var(--hx-shadow);
  backdrop-filter: blur(6px);
}
/* the sheet itself: a hairline-ruled block, closed on all four sides so it
   reads as a page inside the plate rather than a loose list */
.hx-abt .abt-tblock__sheet {
  border: 1px solid var(--hx-line);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.72);
  overflow: hidden;
}
.hx-abt .abt-tblock__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 13px;
  border-bottom: 1px solid var(--hx-line);
  background: rgba(11, 95, 191, 0.045);
  font-family: var(--hx-mono);
  font-size: 13.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hx-dim);
}
.hx-abt .abt-tblock__rows { margin: 0; }
.hx-abt .abt-tblock__rows > div {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: 10px;
  padding: 8px 13px;
  border-top: 1px solid var(--hx-line);
}
.hx-abt .abt-tblock__rows > div:first-child { border-top: 0; }
.hx-abt .abt-tblock__rows dt {
  font-family: var(--hx-mono);
  font-size: 13.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hx-dim);
  padding-top: 3px;
}
.hx-abt .abt-tblock__rows dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.08rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--hx-navy);
  letter-spacing: -0.01em;
}
.hx-abt .abt-tblock__note { min-width: 0; }
.hx-abt .abt-tblock__note .eyebrow { display: inline-flex; margin-bottom: 10px; }
.hx-abt .abt-tblock__note p {
  margin: 0 0 10px;
  max-width: 62ch;
  color: var(--hx-mute);
  font-size: clamp(1.05rem, 1.1vw, 1.06rem);
  line-height: 1.66;
}
.hx-abt .abt-tblock__note p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   3. PORTRAIT, QUOTE, SIGNATURE — the letter furniture
   -------------------------------------------------------------------------- */
.hx-abt .abt-portrait {
  position: relative;
  margin: 0;
  padding: 10px;
  border: 1px solid var(--hx-line);
  border-radius: var(--hx-r);
  background: linear-gradient(165deg, #ffffff, #eef3fa);
  box-shadow: var(--hx-shadow);
}
.hx-abt .abt-portrait img {
  width: 100%;
  /* height:auto beats the height attribute's presentational hint — without it
     the photo renders at its attribute height (stretched, not 5:6) */
  height: auto;
  aspect-ratio: 5 / 6;
  object-fit: cover;
  border-radius: calc(var(--hx-r) - 4px);
  filter: saturate(0.94) contrast(1.03);
}
.hx-abt .abt-portrait figcaption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 4px 2px;
}
.hx-abt .abt-portrait figcaption b { font-family: var(--hx-mono); font-size: 13px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--hx-blue); }
.hx-abt .abt-portrait figcaption span { font-family: var(--hx-mono); font-size: 13.5px; color: var(--hx-dim); }

.hx-abt .abt-quote {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1.9vw, 1.66rem);
  line-height: 1.5;
  font-weight: 500;
  color: var(--hx-navy);
  letter-spacing: -0.01em;
}
.hx-abt .abt-quote::before {
  content: "";
  display: block;
  width: 60px;
  height: 3px;
  margin-bottom: 20px;
  background: linear-gradient(90deg, var(--hx-red), transparent);
}
.hx-abt .abt-sig {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--hx-line);
}
.hx-abt .abt-sig__name { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; color: var(--hx-navy); }
.hx-abt .abt-sig__role { font-family: var(--hx-mono); font-size: 13px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--hx-dim); }
.hx-abt .abt-sig__rule { flex: 1 1 40px; height: 1px; background: var(--hx-line-2); }

/* --------------------------------------------------------------------------
   4. THE STUDIO SECTION — one wide plate, story on the left, points on the
      right. It used to be a portrait collage of two photographs beside a
      narrow copy column; the section is landscape now, the same shape as the
      commitments and regulation sections, and the plate is what keeps the
      prose off the render.
   -------------------------------------------------------------------------- */
.hx-abt .abt-studio {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(18px, 2.2vw, 32px);
  /* the points column is the taller of the two; centring the story against it
     spends the difference on both sides instead of pooling it under the text */
  align-items: center;
}
.hx-abt .abt-studio__story p {
  margin: 0 0 16px;
  color: var(--hx-mute);
  line-height: 1.72;
}
.hx-abt .abt-studio__story p:last-child { margin-bottom: 0; }
/* the letter drops a capital, the way a signed statement does */
.hx-abt .abt-studio__story p:first-child::first-letter {
  float: left;
  margin: 6px 10px 0 0;
  font-family: var(--font-display);
  font-size: 3.05rem;
  font-weight: 700;
  line-height: 0.82;
  color: var(--hx-blue);
}
.hx-abt .abt-studio__points .checks { margin: 0; }
/* --------------------------------------------------------------------------
   5. SCROLL-FOCUS PLATES — opt-in per page, <body data-plate-fade>
   The About pages are read over a live render, so their copy stands on a
   translucent plate. That plate is also exactly what hides the render: it is
   opaque right where the reader is looking. So the plates answer the scroll —
   and they answer it PER ROW, not per card.

   plate-fade.js samples each surface at five heights and writes the result on
   it as keep factors: --plate-1 … --plate-5 (its 0 / 25 / 50 / 75 / 100% rows,
   where 1 is the authored surface and 0.1 — a tenth of the white, so 90%
   transparent — is what a row keeps once it is a third of a window off the
   middle) and --plate-fx, the value at its centre, for what cannot be per-row:
   the backdrop blur, and a grid container's hairline fill. The roll opens with
   a flat band around the centre (plate-fade.js DEAD), so the row crossing the
   middle of the window keeps everything while the rows above and below it have
   already begun to let go. ONE CARD therefore carries several transparencies at
   once — solid where it is being read, clearing towards its ends — which is
   what keeps a tall plate legible in the middle and the render visible around
   it.

   Each surface declares the two alphas the site already paints it at, top and
   bottom (--plate-top / --plate-bottom); the three rows in between are
   interpolated from them. Those numbers come from home3d.css and this file's
   §3–§4, so with no script — or no WebGL, or a page that has not opted in —
   every rule here is exactly the surface the site already had. The shared
   defaults cover anything that has no business being special.

   The card matrix's background transition is switched off: it was there for
   hover, and a 0.45s transition on a value that changes on every scroll frame
   drags a smear behind the wheel.
   -------------------------------------------------------------------------- */
body[data-plate-fade] {
  --plate-top: 0.80;                   /* the shared plate: top and bottom */
  --plate-bottom: 0.62;
}
body[data-plate-fade] :is(
  .hx-plate,
  .grid-2 > div[data-reveal="right"],
  .section-head,
  .card,
  .info-tile,
  .rel-card,
  .std-chip,
  .hx-facts > div,
  .abt-letter,
  .abt-tblock
) {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, calc(var(--plate-top) * var(--plate-1, 1))) 0%,
    rgba(255, 255, 255, calc((0.75 * var(--plate-top) + 0.25 * var(--plate-bottom)) * var(--plate-2, 1))) 25%,
    rgba(255, 255, 255, calc((0.50 * var(--plate-top) + 0.50 * var(--plate-bottom)) * var(--plate-3, 1))) 50%,
    rgba(255, 255, 255, calc((0.25 * var(--plate-top) + 0.75 * var(--plate-bottom)) * var(--plate-4, 1))) 75%,
    rgba(255, 255, 255, calc(var(--plate-bottom) * var(--plate-5, 1))) 100%) !important;
}
/* only the prose plates frost what is behind them. The tiles are dozens to a
   page, and a blur each is a bill the phone pays for every scroll frame. */
body[data-plate-fade] :is(.hx-plate, .grid-2 > div[data-reveal="right"], .section-head, .abt-letter, .abt-tblock) {
  backdrop-filter: blur(calc(3px + 8px * var(--plate-fx, 1)));
}

/* --- the authored values, one line per surface, straight from the sheets ---- */
body[data-plate-fade] .hx-plate,
body[data-plate-fade] .grid-2 > div[data-reveal="right"] { --plate-top: 0.84; --plate-bottom: 0.56; }
body[data-plate-fade] .section-head { --plate-top: 0.84; --plate-bottom: 0.56; }
body[data-plate-fade] .card { --plate-top: 0.80; --plate-bottom: 0.80; }          /* main.css paints it flat */
body[data-plate-fade] .hx-matrix .card { --plate-top: 0.90; --plate-bottom: 0.90; transition: none; }
body[data-plate-fade] .hx-facts > div { --plate-top: 0.76; --plate-bottom: 0.76; }
body[data-plate-fade] .std-chip,
body[data-plate-fade] .rel-card { --plate-top: 0.86; --plate-bottom: 0.86; }
body[data-plate-fade] .info-tile { --plate-top: 0.88; --plate-bottom: 0.80; }
body[data-plate-fade] .abt-letter,
body[data-plate-fade] .abt-tblock { --plate-top: 0.78; --plate-bottom: 0.78; }

/* --------------------------------------------------------------------------
   THE CONTACT FORM — the one surface that does NOT fade
   The form was the only block on the site with no surface at all: the fields
   were white but everything between them — the gaps, the button row and the
   note under the buttons — read straight onto the intake desk. Dark ink over a
   dark desk is the least legible arrangement on the site, and it is worst on
   the smallest type, which is exactly the note.

   It is deliberately NOT in the plate list above (nor in plate-fade.js's
   SELECTOR, which the note there keeps in step with that list). Every other
   surface here fades towards a tenth as it leaves the middle of the window,
   because the render is the point of the page. A form is not decoration: a
   reader scrolls it, types in it and reads the note under the buttons, and a
   control that has thinned to a tenth of its paper has handed the desk back
   through the one block a visitor has to use. So it keeps its paper at every
   scroll position, and takes the blur the prose plates use instead — the blur
   is what protects the glyphs, and it costs the render only its edge, not its
   colour.

   The alphas match the info tiles beside it, so the two columns read as one
   row; the padding is what turns a column of loose inputs into a card. Because
   the form and the tiles share a grid row, the card's top edge lands on the
   first tile's top edge with no nudge — the alignment the page already had.
   -------------------------------------------------------------------------- */
body[data-plate-fade] .form {
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  padding: 20px 22px;
  border: 1px solid var(--hx-line);
  border-radius: var(--hx-r);
  box-shadow: var(--hx-shadow);
}
/* hover still restores a tile: that is the affordance, and a reader who has
   stopped to point at a card is not reading the render through it */
body[data-plate-fade] .hx-matrix .card:hover { background: #fff !important; }

/* the lead-out cell of a matrix is a blue tint rather than white, so it fades
   its own two colours — the same treatment, different pair */
body[data-plate-fade] .hx-matrix__more {
  background: linear-gradient(180deg,
    rgba(228, 238, 251, calc(var(--plate-1, 1))) 0%,
    rgba(241, 247, 253, calc(var(--plate-3, 1))) 50%,
    rgba(255, 255, 255, calc(var(--plate-5, 1))) 100%) !important;
}

/* A grid container carries no surface of its own — only the hairline colour
   showing in the 1px gaps between its tiles, and under them. Once the tiles
   have let go, THAT is the block still covering the render, so it fades on the
   container's own centre value. color-mix keeps it tied to --hx-line instead of
   repeating the token's 0.14 here, where it could drift. */
body[data-plate-fade] :is(.hx-matrix, .hx-facts, .std-strip, .related) {
  background-color: color-mix(in srgb, var(--hx-line) calc(var(--plate-fx, 1) * 100%), transparent);
}

/* --------------------------------------------------------------------------
   6. THE LIVE-MODEL VEILS — <body data-abt="model"> — NOW RETIRED
   These pages exist to show a modelled scene, and the veils used to be aimed
   along the frame instead of across it: the hero's white ran left-to-right so
   the copy column kept its protection and the model kept the right — with half
   a viewport of 90% white in between. The fixed page veil then laid another 22%
   of white over the bottom half and a 26% vignette over the corners, so the
   render arrived at the eye fogged whatever the hero did.

   Both are gone. The copy is legible because of what it carries (the halo in
   home3d.css §HERO COPY, on top of the darkened ink), not because of what lies
   between it and the render. What is left of the model-page identity is one
   faint blue cast, at 6% — a tint, not a veil.
   -------------------------------------------------------------------------- */
body.hx[data-abt="model"]::before {
  background:
    radial-gradient(120% 80% at 78% 42%, rgba(47, 143, 255, 0.06), transparent 62%) !important;
}

/* --------------------------------------------------------------------------
   7. SHARED FURNITURE — the standard light values, nothing re-invented
   -------------------------------------------------------------------------- */
.hx-abt .fab { background: rgba(255, 255, 255, 0.96); border-color: var(--hx-line); color: var(--hx-navy); }
.hx-abt .site-header { box-shadow: 0 1px 0 rgba(12, 42, 84, 0.08); }

/* --------------------------------------------------------------------------
   8. ART-DIRECTION SWITCH — ?solo3d
   The scene is judged with the page curtain out of the way: no copy, no HUD,
   no scrim. Dev-only; the flag lives in the URL and nowhere else.
   -------------------------------------------------------------------------- */
html.abt-solo .hx::before,
html.abt-solo .hx::after,
html.abt-solo .hx-hero::after { display: none !important; }
html.abt-solo main > section > *:not(.hx-hud),
html.abt-solo .site-header,
html.abt-solo .site-footer,
html.abt-solo .hx-hud__hint,
html.abt-solo .hx-rail,
html.abt-solo .fab-stack { visibility: hidden !important; }

/* --------------------------------------------------------------------------
   9. RHYTHM — the About family runs tighter than the shared chapter spacing
   Home and a service page are model-led: their sections need air around the
   render. An About page is prose-led, and 46–78px of padding per section side
   reads as a gap rather than breathing room. The section hairline and the
   section head already carry the separation, so the padding can come down
   without the page filling up. Everything here is family-scoped; the shared
   values in home3d.css are untouched.
   -------------------------------------------------------------------------- */
.hx-abt .section { padding: clamp(26px, 2.4vw, 38px) 0; }
.hx-abt .section-head {
  padding: clamp(12px, 1.3vw, 16px) clamp(18px, 2vw, 24px);
  margin-bottom: clamp(14px, 1.5vw, 18px);
}
.hx-abt .section-head .hx-idx { margin-bottom: 8px; }
.hx-abt .section-head .h-2 { margin-top: 7px; margin-bottom: 8px; }
.hx-abt .section-head .lead { margin-bottom: 0; }
.hx-abt .hx-plate { padding: clamp(16px, 1.7vw, 22px); }
.hx-abt .grid-2 { gap: clamp(18px, 2.1vw, 28px); }
.hx-abt .checks li + li { margin-top: 10px; }
/* the shared card keeps a 196px floor for the model-led pages, where a row of
   short cards would look unfinished under a 3D render. On a prose page the
   floor is just air, so the cards size to their text. */
.hx-abt .hx-matrix .card { min-height: 0; }
/* two-up matrix: the mission/vision pair. No other family renders a 2-across
   tile matrix, so the variant lives here rather than in the shared layer. */
.hx-abt .hx-matrix--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* --------------------------------------------------------------------------
   10. RESPONSIVE
   -------------------------------------------------------------------------- */
/* two columns of plate, and the signature folds back under the body */
@media (max-width: 1180px) {
  .hx-abt .abt-letter { grid-template-columns: 190px minmax(0, 1fr); }
  .hx-abt .abt-letter__sig {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    gap: 6px 16px;
    margin-top: 4px;
    padding: 12px 0 0;
    border-left: 0;
    border-top: 1px solid var(--hx-line);
  }
  .hx-abt .abt-letter__sig .abt-sig__rule { flex: 1 1 40px; width: auto; }
}
@media (max-width: 1024px) {
  .hx-abt .abt-studio { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  /* the title block stacks: the sheet first, the position under it */
  .hx-abt .abt-tblock { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .hx-abt .hx-matrix--2 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .hx-abt .hx-hero { min-height: auto; padding-bottom: 30px; }
  .hx-abt .abt-letter { grid-template-columns: 118px minmax(0, 1fr); gap: 14px; padding: 13px; }
  .hx-abt .abt-letter__salute { margin-bottom: 9px; letter-spacing: 0.14em; }
  .hx-abt .abt-letter .abt-quote { font-size: 1.08rem; line-height: 1.58; }
  .hx-abt .abt-letter .abt-quote::before { width: 34px; margin-bottom: 11px; }
  .hx-abt .abt-letter__sig { gap: 4px 10px; padding-top: 11px; }
  .hx-abt .abt-sig__name { font-size: 1.05rem; }
  .hx-abt .abt-tblock__rows > div { grid-template-columns: 88px minmax(0, 1fr); padding: 7px 11px; }
  .hx-abt .abt-tblock__rows dd { font-size: 1.02rem; }
}
@media (max-width: 560px) {
  .hx-abt .abt-letter { grid-template-columns: minmax(0, 1fr); }
  .hx-abt .abt-letter .abt-portrait { width: min(60%, 200px); }
}

/* READABILITY PASS — 2026-09-27: page meta print stays at 13px or more. */
small, dt, figcaption, .hx-facts dt, .hx-facts dd { font-size: max(13px, 0.82em); }
small, dt, figcaption { font-weight: 500; }
