/* ==========================================================================
   SHIFT — Components
   ========================================================================== */

/* --------------------------------------------------------------------------
   Logo. Delivered as a CSS mask so one cached SVG takes any colour, in any
   theme, with no inline duplication and no JS.
   -------------------------------------------------------------------------- */
.logo {
  display: block;
  aspect-ratio: 2250 / 1242;
  background-color: currentColor;
  -webkit-mask: url("../img/shift-logo.svg") no-repeat center / contain;
  mask: url("../img/shift-logo.svg") no-repeat center / contain;
}
.logo--header { height: 1.5rem; width: 2.72rem; }
.logo--footer { height: 2.75rem; width: 4.98rem; }
@media (min-width: 48em) { .logo--header { height: 1.75rem; width: 3.17rem; } }

/* ==========================================================================
   Header
   ========================================================================== */

.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  padding-top: var(--s-5); padding-bottom: var(--s-5);
  transition: padding var(--d-comp) var(--e-mech),
              background-color var(--d-comp) linear;
}
.header::after {
  content: "";
  position: absolute; inset: 0;
  /* A blurred backdrop here meant re-blurring the whole strip on every
     scroll frame, which is most of what made desktop scrolling feel heavy.
     An opaque-enough tint reads the same over a flat page and costs nothing. */
  background: var(--c-base);
  background: color-mix(in srgb, var(--c-base) 94%, transparent);
  border-bottom: var(--hair) solid transparent;
  opacity: 0;
  transition: opacity var(--d-comp) linear,
              border-color var(--d-comp) linear;
  z-index: -1;
}
.header.is-stuck { padding-top: var(--s-3); padding-bottom: var(--s-3); }
.header.is-stuck::after { opacity: 1; border-bottom-color: var(--c-line); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}

.header__brand {
  color: var(--c-ink);
  display: flex; align-items: center; gap: var(--s-3);
  flex: none;
  transition: opacity var(--d-micro) var(--e-shift);
}
.header__brand:hover { opacity: 0.62; }

/* --------------------------------------------------------------------------
   The nav rail.
   A bordered track holding the tabs. A solid graphite block marks the current
   page and physically slides between tabs — the site's core gesture at nav
   scale. Hover pushes the block halfway toward the hovered tab, so the shift
   is previewed before it commits.
   -------------------------------------------------------------------------- */
.rail {
  position: relative;
  display: none;
  align-items: center;
  padding: 4px;
  border: var(--hair) solid var(--c-line);
  border-radius: 999px;
  background: var(--c-paper);
  background: color-mix(in srgb, var(--c-paper) 70%, transparent);
  isolation: isolate;
}
@media (min-width: 62em) { .rail { display: flex; } }

/* The travelling block. Position is written by nav.js as CSS variables. */
.rail__block {
  position: absolute;
  top: 4px; bottom: 4px;
  left: 0;
  width: var(--block-w, 0px);
  transform: translateX(var(--block-x, 0px));
  background: var(--c-ink);
  border-radius: 999px;
  z-index: -1;
  transition: transform var(--d-comp) var(--e-mech),
              width var(--d-comp) var(--e-mech);
}
.rail:not(.is-ready) .rail__block { opacity: 0; }

.rail__link {
  position: relative;
  padding: 0.55rem 1.15rem;
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--c-ink-2);
  white-space: nowrap;
  border-radius: 999px;
  transition: color var(--d-comp) var(--e-mech);
}
.rail__link:hover { color: var(--c-ink); }
/* Only flip the current tab to light once the block is actually behind it.
   Until then it stays dark, so it can never be invisible. */
.rail.is-ready .rail__link[aria-current] { color: var(--c-on-ink); }
.rail__link[aria-current] { color: var(--c-ink); }
.rail.is-ready .rail__link[aria-current]:hover { color: var(--c-on-ink); }

/* Chevron leading the block — lifted straight off the logo's terminals. */
.rail__chev {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(var(--chev-x, 0px), -50%);
  color: var(--c-accent);
  font-family: var(--f-mono);
  font-size: 0.7rem;
  opacity: 0;
  pointer-events: none;
  transition: transform var(--d-comp) var(--e-mech), opacity var(--d-micro) linear;
}
.rail:hover .rail__chev { opacity: 1; }

.header__actions { display: flex; align-items: center; gap: var(--s-3); flex: none; }

/* Below the rail breakpoint the contact button would push the burger off the
   edge of a 375px screen. Contact lives in the mobile menu instead. */
@media (max-width: 61.99em) {
  .header__actions > .btn { display: none; }
}

/* --------------------------------------------------------------------------
   Language switch, and the light/dark switch beside it — a two-cell track
   whose thumb shifts. Same gesture again, one size down.

   They share the track so the pair reads as one control family. The theme
   switch carries icons rather than words: LIGHT/DARK would be twice the
   width of JA/EN and would unbalance the header, and two text pills side by
   side are harder to tell apart at a glance than one worded and one drawn.
   -------------------------------------------------------------------------- */
.lang, .theme {
  position: relative;
  display: flex;
  padding: 3px;
  border: var(--hair) solid var(--c-line);
  border-radius: 999px;
  isolation: isolate;
}
.lang__thumb, .theme__thumb {
  position: absolute;
  top: 3px; bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  background: var(--c-accent);
  border-radius: 999px;
  z-index: -1;
  transition: transform var(--d-comp) var(--e-mech);
}
[data-lang="en"] .lang__thumb { transform: translateX(100%); }
/* Keyed on a class rather than on [data-theme], because data-theme is only
   ever set once the user actually picks one. Before that the OS decides the
   colours, and the thumb still has to show which side is really showing. */
.theme.is-dark .theme__thumb { transform: translateX(100%); }

.lang__btn, .theme__btn {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.08em;
  padding: 0.4rem 0.6rem;
  min-width: 2.5rem;
  color: var(--c-muted);
  border-radius: 999px;
  transition: color var(--d-comp) var(--e-mech);
}
.lang__btn[aria-pressed="true"],
.theme__btn[aria-pressed="true"] { color: var(--c-on-accent); }

/* Narrower than the language cells: an icon needs less room than two letters,
   and the header still has to fit a 375px screen. */
.theme__btn { min-width: 2.1rem; padding: 0.4rem 0.5rem; display: grid; place-items: center; }
.theme__btn svg { display: block; width: 15px; height: 15px; }

/* Touch targets. The cells are 34-40px wide and under 32px tall, which is
   below the 44px a thumb wants — fine for a mouse, not for a phone. Rather
   than inflate the pills and unbalance the header, each cell grows an
   invisible 44px-tall hit area, vertically only: extending it sideways too
   would make neighbouring cells overlap and steal each other's edge.
   Coarse pointers only, so a mouse still gets exactly the drawn control. */
.lang__btn, .theme__btn { position: relative; }
@media (pointer: coarse) {
  .lang__btn::after, .theme__btn::after {
    content: "";
    position: absolute;
    left: 0; right: 0; top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
  /* The logo link is 24px tall for the same reason. */
  .header__brand { position: relative; }
  .header__brand::after {
    content: "";
    position: absolute;
    left: 0; right: 0; top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
}

/* --------------------------------------------------------------------------
   Menu button — two bars, offset from each other. They align on hover, then
   cross into an X when open.
   -------------------------------------------------------------------------- */
.burger {
  --bar: 2px;
  appearance: none; border: 0; background: none; cursor: pointer;
  width: 44px; height: 44px;
  display: grid; place-content: center; gap: 5px;
  margin-right: calc(var(--s-2) * -1);
}
@media (min-width: 62em) { .burger { display: none; } }

.burger__bar {
  display: block;
  width: 22px; height: var(--bar);
  background: var(--c-ink);
  transition: transform var(--d-comp) var(--e-mech), opacity var(--d-micro) linear;
}
.burger__bar:nth-child(1) { transform: translateX(-3px); }
.burger__bar:nth-child(2) { transform: translateX(3px); }
.burger:hover .burger__bar { transform: translateX(0); }

[data-menu="open"] .burger__bar:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
[data-menu="open"] .burger__bar:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   Mobile menu — items arrive as panels sliding in from alternating sides.
   -------------------------------------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--c-base);
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: var(--s-5) 0 var(--s-7);
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--d-comp) linear, visibility 0s linear var(--d-comp);
}
[data-menu="open"] .menu {
  visibility: visible; opacity: 1;
  transition: opacity var(--d-comp) linear, visibility 0s;
}
@media (min-width: 62em) { .menu { display: none; } }

.menu__list { display: grid; align-content: center; gap: var(--s-2); }

.menu__item {
  border-bottom: var(--hair) solid var(--c-line-soft);
  overflow: hidden;
}
.menu__link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-top: var(--s-4); padding-bottom: var(--s-4);
  font-size: clamp(1.75rem, 8vw, 2.75rem);
  font-weight: 600;
  letter-spacing: var(--tr-tight);
  transform: translateX(var(--from, -110%));
  opacity: 0;
  transition: transform var(--d-sect) var(--e-shift), opacity var(--d-comp) linear;
  transition-delay: calc(var(--i, 0) * var(--stagger));
}
.menu__item:nth-child(even) .menu__link { --from: 110%; }
[data-menu="open"] .menu__link { transform: translateX(0); opacity: 1; }
.menu__link[aria-current] { color: var(--c-accent); }
.menu__link .num { font-size: var(--t-label); color: var(--c-muted); }

.menu__foot { display: grid; gap: var(--s-3); }

/* ==========================================================================
   Buttons
   The label rolls: the current text shifts up and out while a duplicate
   arrives from below. Movement, not decoration — it reads as a mechanism.
   ========================================================================== */

.btn {
  --btn-bg: var(--c-ink);
  --btn-fg: var(--c-on-ink);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 46px;
  padding: 0.8rem 1.6rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--hair) solid var(--btn-bg);
  border-radius: 999px;
  cursor: pointer;
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.005em;
  overflow: hidden;
  isolation: isolate;
  transition: background-color var(--d-comp) var(--e-mech),
              border-color var(--d-comp) var(--e-mech),
              color var(--d-comp) var(--e-mech);
}
.btn:hover { --btn-bg: var(--c-accent); border-color: var(--c-accent); --btn-fg: var(--c-on-accent); }
.btn:active { transform: translateY(1px); }

.btn__roll { position: relative; display: grid; overflow: hidden; }
.btn__roll > span {
  grid-area: 1 / 1;
  transition: transform var(--d-comp) var(--e-shift), opacity var(--d-micro) linear;
}
.btn__roll > span:last-child { transform: translateY(110%); opacity: 0; }
.btn:hover .btn__roll > span:first-child { transform: translateY(-110%); opacity: 0; }
.btn:hover .btn__roll > span:last-child { transform: translateY(0); opacity: 1; }

.btn__chev {
  flex: none;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  transition: transform var(--d-comp) var(--e-shift);
}
.btn:hover .btn__chev { transform: translateX(4px); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--c-ink); border-color: var(--c-line); }
.btn--ghost:hover { --btn-bg: var(--c-ink); --btn-fg: var(--c-on-ink); border-color: var(--c-ink); }
.btn--sm { min-height: 40px; padding: 0.55rem 1.15rem; }
.btn--full { width: 100%; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn:disabled:hover { --btn-bg: var(--c-ink); border-color: var(--c-ink); }

/* Text link with a rule that shifts across on hover. */
.link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  color: var(--c-ink);
  font-weight: 500;
  padding-bottom: 2px;
  background-image: linear-gradient(var(--c-accent), var(--c-accent));
  background-size: 0% var(--hair);
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--d-comp) var(--e-mech), color var(--d-micro) linear;
}
.link:hover { background-size: 100% var(--hair); color: var(--c-accent); }
.link__chev { font-family: var(--f-mono); font-size: 0.75rem; transition: transform var(--d-comp) var(--e-shift); }
.link:hover .link__chev { transform: translateX(4px); }

/* ==========================================================================
   Cards
   Hovering shifts the card and pushes its siblings aside — tiles making room.
   ========================================================================== */

.card {
  position: relative;
  display: grid;
  gap: var(--s-4);
  padding: var(--s-6);
  background: var(--surface);
  border: var(--hair) solid var(--c-line);
  border-radius: var(--radius-lg);
  transition: transform var(--d-comp) var(--e-shift),
              border-color var(--d-comp) linear,
              background-color var(--d-comp) linear;
}
.card:hover { transform: translate(3px, -3px); border-color: var(--c-accent); }
.card__index { display: flex; justify-content: space-between; align-items: center; gap: var(--s-4); }
.card__title {
  font-size: var(--t-h3);
  font-weight: 700;
  letter-spacing: var(--tr-tight);
  color: var(--c-accent);
}
/* A rule between the title and the detail, so the eye knows where the
   heading stops and the explanation starts. */
.card__body {
  color: var(--c-ink-2);
  font-size: var(--t-small);
  line-height: 1.75;
  padding-top: var(--s-4);
  border-top: var(--hair) solid var(--c-line);
  text-wrap: pretty;
}

/* Whole-card link overlay, keeps one tab stop and a real focus ring. */

/* ==========================================================================
   Numbered badge — the anchor at the top-left of anything explained in steps
   ========================================================================== */

/* A package, drawn rather than faked with gradients. CSS could not give
   identical pins on four edges — each edge's gradient started at its own
   offset — and could not show anything inside the body at all. The chip is
   an SVG: sixteen pins of exactly the same size, a body you can see through,
   and a die with bond wires visible inside it. */
.badge {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  color: var(--c-accent);
}
.badge__pkg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* The number sits above the package and is the darkest thing in it. */
.badge__n {
  position: relative;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--c-accent);
}

/* ==========================================================================
   Service cards
   Each explanation is a box: a number to anchor it, a coloured title, one
   bold line that carries the point, then the detail underneath. Scannable
   without being read.
   ========================================================================== */

.scards { display: grid; gap: var(--s-4); }

.scard {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-5);
  padding: var(--s-6);
  background: var(--surface);
  border: var(--hair) solid var(--c-line);
  border-radius: var(--radius-lg);
  transition: transform var(--d-comp) var(--e-shift),
              border-color var(--d-comp) linear,
              background-color var(--d-comp) linear;
}
@media (max-width: 47.99em) {
  .scard { grid-template-columns: 1fr; gap: var(--s-4); padding: var(--s-5); }
}
.scard:hover { transform: translate(4px, -4px); border-color: var(--c-accent); }

.scard__main { display: grid; gap: var(--s-3); min-width: 0; }

.scard__title {
  font-size: var(--t-h3);
  font-weight: 700;
  letter-spacing: var(--tr-tight);
  color: var(--c-accent);
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
}
.scard__title .chev {
  font-family: var(--f-mono);
  font-size: 0.7em;
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--d-comp) linear, transform var(--d-comp) var(--e-shift);
}
.scard:hover .scard__title .chev { opacity: 1; transform: translateX(0); }

/* The one line to read if you read nothing else. */
.scard__summary {
  font-size: var(--t-lead);
  font-weight: 600;
  line-height: 1.5;
  color: var(--c-ink);
  text-wrap: pretty;
}

.scard__body {
  color: var(--c-ink-2);
  font-size: var(--t-small);
  line-height: 1.78;
  padding-top: var(--s-4);
  border-top: var(--hair) solid var(--c-line);
  text-wrap: pretty;
}

.scard__tags { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* ==========================================================================
   Callout — a statement worth boxing off from the paragraphs around it
   ========================================================================== */

.callout {
  padding: var(--s-6);
  background: var(--c-accent-lo);
  border-left: 3px solid var(--c-accent);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}
.callout > * + * { margin-top: var(--s-4); }
.callout__lead {
  font-size: var(--t-lead);
  font-weight: 600;
  line-height: 1.55;
  color: var(--c-ink);
  text-wrap: pretty;
}

/* Numbered service rows — a spec sheet that opens on hover. */
@media (min-width: 48em) {
}
@media (min-width: 48em) { .spec__body { grid-column: auto; } }
.tag {
  font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: 0.1em;
  padding: 0.3rem 0.7rem;
  border: var(--hair) solid var(--c-line);
  border: var(--hair) solid color-mix(in srgb, var(--c-accent) 32%, transparent);
  background: var(--c-accent-lo);
  border-radius: 999px; color: var(--c-accent); text-transform: uppercase;
}

/* ==========================================================================
   Venture bento — asymmetric tiles that make room for each other
   ========================================================================== */

@media (max-width: 47.99em) { .bento { grid-template-columns: 1fr; } }

@media (min-width: 48em) and (max-width: 63.99em) {
}
@media (max-width: 47.99em) {
}

/* Accent panel sweeps in from the left on hover. */
/* ==========================================================================
   Ventures list
   Deliberately quiet. These are things SHIFT happens to own, not the pitch —
   a name, a line, and a way out to their own site if you care.
   ========================================================================== */

.vlist { border-top: var(--hair) solid var(--c-line); }

.vrow {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-2);
  padding-top: var(--s-5); padding-bottom: var(--s-5);
  padding-left: var(--s-3); padding-right: var(--s-3);
  margin-left: calc(var(--s-3) * -1); margin-right: calc(var(--s-3) * -1);
  border-bottom: var(--hair) solid var(--c-line);
  transition: background-color var(--d-comp) linear,
              transform var(--d-comp) var(--e-shift);
}
@media (min-width: 48em) {
  .vrow { grid-template-columns: 13rem 1fr auto; gap: var(--s-6); align-items: baseline; }
}

.vrow__name {
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: var(--tr-tight);
}
.vrow__desc { color: var(--c-ink-2); font-size: var(--t-small); line-height: 1.7; }


/* Only the rows that actually go somewhere respond to a pointer. */
a.vrow { color: inherit; }
a.vrow:hover { background: var(--surface-sunk); transform: translateX(4px); }
a.vrow:hover .vrow__go span { transform: translateX(4px); }

/* ==========================================================================
   会社概要 table — the standard Japanese company profile block
   ========================================================================== */

.profile { border-top: var(--hair) solid var(--c-ink); width: 100%; }
.profile__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-1);
  padding-top: var(--s-4); padding-bottom: var(--s-4);
  border-bottom: var(--hair) solid var(--c-line);
}
@media (min-width: 40em) {
  .profile__row { grid-template-columns: 12rem 1fr; gap: var(--s-6); align-items: baseline; }
}
.profile__key { font-size: var(--t-small); font-weight: 500; color: var(--c-muted); }
.profile__val { font-size: var(--t-body); }
.profile__val .num { font-size: 0.95em; }

/* 事業内容 is the seven 目的 exactly as they are registered, so it is set as a
   numbered list rather than a run-on sentence — that is how it reads on the
   履歴事項全部証明書, and it is the one block on this page where matching the
   register is the whole point.

   The counter is drawn rather than left to the browser: list-style numerals
   inherit the body face and sit outside the box, which on a phone either
   overhangs the column or gets clipped. A mono counter placed in the flow
   keeps it aligned with the numerals elsewhere on the page and lets the text
   wrap under itself. */
.purposes { list-style: none; display: grid; gap: var(--s-2); }
.purposes li {
  display: grid;
  grid-template-columns: 1.6em 1fr;
  align-items: baseline;
  font-size: var(--t-small);
  line-height: 1.7;
  counter-increment: purpose;
}
.purposes li::before {
  content: counter(purpose);
  font-family: var(--f-mono);
  font-size: 0.8em;
  color: var(--c-muted);
  font-variant-numeric: tabular-nums;
}
.purposes { counter-reset: purpose; }

/* ==========================================================================
   Forms
   ========================================================================== */

.field { display: grid; gap: var(--s-2); }
.field__label { font-size: var(--t-small); font-weight: 500; display: flex; align-items: center; gap: var(--s-2); }
.field__req { color: var(--c-accent); font-family: var(--f-mono); font-size: var(--t-label); }
.field__hint { font-size: var(--t-small); color: var(--c-muted); line-height: 1.5; }

.input {
  width: 100%;
  min-height: 48px;
  padding: 0.75rem 1rem;
  background: var(--surface-lift);
  border: var(--hair) solid var(--c-line);
  border-radius: var(--radius);
  color: var(--c-ink);
  transition: border-color var(--d-micro) linear, background-color var(--d-micro) linear;
}
.input::placeholder { color: var(--c-muted); opacity: 0.7; }
.input:hover { border-color: var(--c-muted); }
.input:focus { border-color: var(--c-accent); outline-offset: 1px; }
textarea.input { min-height: 9rem; resize: vertical; line-height: 1.65; }
select.input { cursor: pointer; }

.field__error {
  display: none;
  font-size: var(--t-small);
  color: var(--c-danger);
  align-items: center;
  gap: var(--s-2);
}
.field__error::before { content: "!"; font-family: var(--f-mono); font-weight: 700; }
.field.is-invalid .field__error { display: flex; }
.field.is-invalid .input { border-color: var(--c-danger); }

.form__status {
  padding: var(--s-4);
  border: var(--hair) solid var(--c-line);
  border-radius: var(--radius);
  font-size: var(--t-small);
  background: var(--surface-lift);
}
.form__status:empty { display: none; }
.form__status.is-ok { border-color: var(--c-ok); color: var(--c-ok); }
.form__status.is-err { border-color: var(--c-danger); color: var(--c-danger); }

/* ==========================================================================
   Footer
   ========================================================================== */

.footer { background: var(--c-ink); color: var(--c-on-ink); padding-top: var(--s-9); padding-bottom: var(--s-6); }
.footer a { color: var(--c-on-ink); }
.footer__grid { display: grid; gap: var(--s-8); grid-template-columns: 1fr; }
@media (min-width: 48em) { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; gap: var(--s-6); } }
.footer__head { display: grid; gap: var(--s-4); max-width: 24rem; }
.footer__col { display: grid; gap: var(--s-3); align-content: start; }
.footer__label { font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: #9C9A94;
  color: color-mix(in srgb, var(--c-on-ink) 55%, transparent); }
.footer__link {
  font-size: var(--t-small);
  display: inline-flex; align-items: center; gap: var(--s-2);
  opacity: 0.82;
  transition: opacity var(--d-micro) linear, transform var(--d-comp) var(--e-shift);
}
.footer__link:hover { opacity: 1; transform: translateX(4px); }
.footer__bottom {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: var(--hair) solid #3A3C3D;
  border-top: var(--hair) solid color-mix(in srgb, var(--c-on-ink) 18%, transparent);
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  justify-content: space-between; align-items: center;
  font-size: var(--t-label); font-family: var(--f-mono);
  color: #9C9A94;
  color: color-mix(in srgb, var(--c-on-ink) 55%, transparent);
  letter-spacing: 0.1em;
}

/* ==========================================================================
   Page hero (interior pages)
   ========================================================================== */

.phero { padding-top: calc(var(--section) + 3rem); padding-bottom: var(--section); position: relative; }
.phero__title { max-width: 16ch; }

/* A short aside under a card's summary — used to say plainly what a term
   means before the detail assumes you know it. */
.scard__note {
  font-size: var(--t-small);
  line-height: 1.7;
  color: var(--c-ink-2);
  padding: var(--s-3) var(--s-4);
  border-left: 2px solid var(--c-accent);
  background: var(--c-accent-lo);
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* A venture that has no site yet. Reads as a state, not a dead link — muted
   and unclickable, so nobody hunts for a URL that isn't there. */
.vrow__status {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--c-muted);
  white-space: nowrap;
  align-self: center;
}

/* ─────────────────────────────────────────────────────────────────────────────
   CONTACT FORM
   Built on the committed system: same hairlines, same type scale, the existing
   .btn for submit. No new colour — focus and errors reuse --c-accent and
   --c-danger, which already carry their meaning everywhere else on the site.

   No placeholders anywhere. A placeholder that doubles as a label disappears
   the moment someone types, which is exactly when a person re-checks what a
   field wanted; and placeholder grey never clears 4.5:1 against a light panel.
   Every field keeps a visible label instead.
   ───────────────────────────────────────────────────────────────────────────── */
.contact__direct { margin-top: var(--s-5); }
.contact__direct .t-small { margin-top: var(--s-2); }

.form { display: grid; gap: var(--s-4); }
/* Two-up on desktop, stacked on phones. minmax(0,1fr) not 1fr: a long
   autofilled value would otherwise widen the column and break the grid. */
.form__row { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--s-4); }
@media (max-width: 40em) { .form__row { grid-template-columns: minmax(0,1fr); } }

.field { display: grid; gap: var(--s-2); min-width: 0; }
.field__label {
  font-size: var(--fs-small, .8125rem); font-weight: 600;
  letter-spacing: .04em; color: var(--c-ink-2);
  display: flex; align-items: baseline; gap: var(--s-2);
}
.field__opt { font-style: normal; font-weight: 400; font-size: .875em; color: var(--c-muted); letter-spacing: .02em; }

.field__input {
  width: 100%; font: inherit; font-size: 1rem;   /* 16px floor: iOS zooms the page on focus below it */
  color: var(--c-ink); background: var(--c-paper);
  border: 1px solid var(--c-line); border-radius: 2px;
  padding: .7rem .8rem; -webkit-appearance: none; appearance: none;
  transition: border-color .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s cubic-bezier(.2,.7,.3,1), background-color .16s;
}
.field__input--area { resize: vertical; min-height: 8.5rem; line-height: 1.6; }
.field__input:hover { border-color: var(--c-ink-2); }
.field__input:focus-visible,
.field__input:focus {
  outline: none; border-color: var(--c-accent);
  /* a ring, not a glow: it reads as focus at any zoom and survives high contrast */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 22%, transparent);
}
.field__input:disabled { background: var(--c-sunk); color: var(--c-muted); cursor: not-allowed; }

.field--bad .field__input { border-color: var(--c-danger); }
.field--bad .field__input:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-danger) 22%, transparent); }
.field__err {
  font-size: .8125rem; line-height: 1.45; color: var(--c-danger);
  /* the message arrives rather than blinking on — an error is the one moment
     the eye must be led, and a 120ms slide does that without theatre */
  animation: fieldErr .16s cubic-bezier(.2,.7,.3,1) both;
}
@keyframes fieldErr { from { opacity: 0; transform: translateY(-2px) } to { opacity: 1; transform: none } }

/* Off-screen, not display:none — a hidden input is skipped by autofill and by
   some bots, and being genuinely positioned is what makes the trap credible. */
.form__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__submit { margin-top: var(--s-1); }
.form__submit[disabled] { opacity: .55; pointer-events: none; }

.form__status { font-size: .875rem; line-height: 1.5; margin: 0; min-height: 1.4em; }
.form__status:empty { display: none; }
.form__status--ok { color: var(--c-ok); }
.form__status--bad { color: var(--c-danger); }
.form__note { margin-top: var(--s-1); }

@media (prefers-reduced-motion: reduce) {
  .field__input { transition: none; }
  .field__err { animation: none; }
}
