/* ==========================================================================
   Sumire Construction — Design tokens & base styles
   ========================================================================== */

:root {
  /* Colors */
  --color-bg: #f7f6f2;
  --color-white: #ffffff;
  --color-text: #202020;
  --color-text-sub: #696969;
  --color-charcoal: #3c3c3c;
  --color-border: #ddddda;
  /* Sampled directly from assets/images/logo.png — update these two if the
     logo file is ever replaced with different brand colors. */
  --color-green: #3a8e65;
  --color-purple: #7d6eb2;
  --color-green-soft: rgba(58, 142, 101, 0.08);
  --color-purple-soft: rgba(125, 110, 178, 0.08);
  /* Muted terracotta rather than a pure alert red — form errors still need
     to read clearly, just without a jarring, "urgent" tone. */
  --color-error: #b3452c;

  /* Fonts */
  --font-ja: "Noto Sans JP", sans-serif;
  --font-en: "Inter", sans-serif;
  --font-heading: "Shippori Mincho", serif;

  /* Spacing scale (8px base) */
  --space-3xs: 4px;
  --space-2xs: 8px;
  --space-xs: 12px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 32px;
  --space-xl: 48px;
  --space-2xl: 64px;
  --space-3xl: 96px;
  --section-space-large: clamp(100px, 12vw, 190px);
  --section-space-medium: clamp(72px, 9vw, 130px);

  /* Layout */
  --content-width: 1240px;
  --container-pad: clamp(1.25rem, 4vw, 3rem);
  --header-height: 88px;
  --radius-sm: 2px;

  /* Typography scale */
  --fs-micro: 0.75rem;
  --fs-small: 0.875rem;
  --fs-body: 1.25rem;
  --fs-lead: 1.375rem;
  --fs-h2: clamp(1.75rem, 1.2rem + 2.8vw, 3rem);
  --fs-hero: clamp(3.5rem, 6vw, 6.8rem);
  --lh-body: 1.9;
  --lh-heading: 1.5;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --duration-base: 0.85s;
  --duration-fast: 0.3s;
  --reveal-distance: 32px;
}

html {
  scroll-behavior: smooth;
}

body {
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-ja);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  overflow-x: hidden;
}

body.no-scroll {
  overflow: hidden;
}

img, video, iframe, table {
  max-width: 100%;
  height: auto;
}

h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: var(--lh-heading);
}

a {
  transition: color var(--duration-fast) ease, border-color var(--duration-fast) ease,
    background-color var(--duration-fast) ease;
}

section[id] {
  scroll-margin-top: var(--header-height);
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.section__inner {
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section {
  padding-block: var(--section-space-medium);
  border-top: 1px solid var(--color-border);
}

.section--large {
  padding-block: var(--section-space-large);
}

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

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-height);
  background-color: transparent;
  transition: background-color var(--duration-fast) ease, box-shadow var(--duration-fast) ease,
    backdrop-filter var(--duration-fast) ease;
}

.site-header--scrolled {
  background-color: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(12px);
  box-shadow: 0 1px 0 var(--color-border);
}

.site-header__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.site-header__logo {
  display: flex;
  align-items: center;
}

.site-header__logo img {
  height: 80px;
  width: 250px;
  object-fit: fill;
}

.site-nav__list {
  display: flex;
  gap: var(--space-lg);
}

.site-nav__list a {
  font-size: var(--fs-small);
  letter-spacing: 0.02em;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}

.site-nav__list a:hover,
.site-nav__list a.is-active {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 1px;
  background-color: var(--color-text);
  transition: transform var(--duration-fast) ease, opacity var(--duration-fast) ease;
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* Mobile nav is only hidden off-canvas once JS confirms it can be toggled
   back open again — see responsive.css. Without JS it stays in normal flow
   so every link remains reachable. */

/* ==========================================================================
   Section heading (shared by every section)
   ========================================================================== */

.section-heading {
  max-width: 640px;
}

.section-heading__en {
  display: block;
  font-family: var(--font-en);
  font-size: 1rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-green);
  margin-bottom: var(--space-sm);
}

.section-heading__ja {
  font-size: var(--fs-h2);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.section-hero {
  position: relative;
  overflow: hidden;
  padding-block: 0;
  border-top: none;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
}

.section-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  /* Bright, neutral placeholder — swapped for the real photo below once it
     loads. Deliberately light (no heavy dark overlay), matching the brand's
     "bright, dignified" direction rather than a heavy construction-noir look. */
  background: linear-gradient(135deg, #f3f1ec 0%, #ffffff 55%, #edf2ee 100%);
}

.section-hero__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 60%;
}

/* Photo-specific reveal: reuses .hero-reveal's is-visible trigger/timing
   (see intro.js) but overrides the generic blur+translateY treatment —
   sliding a full-bleed background photo would expose a gap at one edge
   inside .section-hero__media's overflow:hidden. A zoom-settle instead,
   then a slow, barely-there drift so the hero doesn't feel static. Both
   stages are pure transform/opacity (compositor-friendly, no layout cost). */
.js .section-hero__photo.hero-reveal {
  opacity: 0;
  transform: scale(1.12);
  filter: none;
  transition:
    opacity 2.6s var(--ease-out),
    transform 3s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .section-hero__photo.hero-reveal.is-visible {
  opacity: 1;
  transform: scale(1);
  /* Starts right as the settle transition above finishes (3s) — its own
     0% keyframe matches scale(1) so there's no visible handoff jump. */
  animation: hero-photo-drift 22s var(--ease-out) 3s infinite alternate;
}

@keyframes hero-photo-drift {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.06);
  }
}

/* Soft white fade behind the header row so the logo/nav stay legible over a
   busy photo without darkening the photo itself. */
.section-hero__media::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(var(--header-height) * 1.8);
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0));
  pointer-events: none;
}

.section-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Widened/strengthened so the heading's second line (which overflows
     .section-hero__inner's max-width via white-space:nowrap on .hero-line)
     stays over a legible backdrop instead of the busy photo detail
     (machinery edges/high-contrast yellow) further right. */
  background: linear-gradient(
    90deg,
    rgba(247, 246, 242, 0.95) 0%,
    rgba(247, 246, 242, 0.88) 45%,
    rgba(247, 246, 242, 0.55) 70%,
    rgba(247, 246, 242, 0.15) 88%,
    rgba(247, 246, 242, 0) 100%
  );
  pointer-events: none;
}

.section-hero__inner {
  position: relative;
  z-index: 2;
  padding-top: var(--header-height);
  max-width: min(900px, 92vw);
}

.section-hero__heading {
  font-size: var(--fs-hero);
  margin-block: var(--space-md);
}

.hero-line {
  display: block;
  white-space: nowrap;
}

.section-hero__sub {
  max-width: 560px;
  font-size: var(--fs-lead);
  color: var(--color-text-sub);
}

.section-hero__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.section-hero__link {
  font-size: var(--fs-small);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--color-border);
}

.section-hero__link:hover,
.section-hero__link:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

.section-hero__scroll {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: var(--space-lg);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  color: var(--color-text-sub);
}

.section-hero__scroll::after {
  content: "";
  width: 1px;
  height: 28px;
  background: var(--color-border);
}

/* ==========================================================================
   About (#about) — first fully designed section below the hero.
   Scoped entirely under .section-about so it never affects the generic
   .section-content system still used by Service/Policy/Works/etc.
   ========================================================================== */

.section-about {
  position: relative;
  overflow: hidden;
}

.about__inner {
  position: relative;
}

.about__bg-text {
  position: absolute;
  top: -0.15em;
  right: -0.04em;
  z-index: 0;
  margin: 0;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: clamp(6rem, 18vw, 14rem);
  line-height: 1;
  color: var(--color-green);
  opacity: 0.05;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.about__content {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(460px, 0.95fr) minmax(360px, 1.05fr);
  gap: var(--space-2xl);
  align-items: start;
}

/* Deliberately not position:sticky — combined with this grid's track
   sizing it produced a genuine layout bug (the copy column's later
   siblings measured against a stale, pre-reflow heading height and
   overlapped it). A plain static heading avoids that class of bug
   entirely; the brief was explicit that sticky here was optional. */
.about__heading {
  position: static;
}

.section-heading__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

/* .section-heading__en's own margin-bottom (needed when it stands alone,
   e.g. the Hero eyebrow) throws off align-items:center here — the extra
   margin box height nudges the text upward relative to the number. */
.section-heading__eyebrow .section-heading__en {
  margin-bottom: 0;
}

.section-heading__number {
  font-family: var(--font-en);
  font-weight: 600;
  font-size: 1.75rem;
  color: var(--color-purple);
}

.about__heading .section-heading__en {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-bottom: 0;
}

.about__heading .section-heading__en::after {
  content: "";
  width: 22px;
  height: 1px;
  background-color: var(--color-green);
}

.about__heading .section-heading__ja {
  font-size: clamp(2.2rem, 3.4vw, 4.2rem);
}

.about__body {
  margin-top: var(--space-xl);
  max-width: 36rem;
}

.about__body p {
  color: var(--color-text);
  line-height: 2;
}

.about__body p + p {
  margin-top: var(--space-md);
}

.about__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: var(--space-xl);
  font-size: var(--fs-small);
  color: var(--color-text);
}

.about__link::after {
  content: "\2192";
  transition: transform 0.3s var(--ease-out), color 0.3s ease;
}

.about__link span {
  position: relative;
}

.about__link span::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1px;
  background-color: var(--color-border);
  transform: scaleX(0.6);
  transform-origin: left;
  transition: transform 0.3s var(--ease-out), background-color 0.3s ease;
}

.about__link:hover,
.about__link:focus-visible {
  color: var(--color-green);
}

.about__link:hover span::after,
.about__link:focus-visible span::after {
  transform: scaleX(1);
  background-color: var(--color-green);
}

.about__link:hover::after,
.about__link:focus-visible::after {
  transform: translateX(4px);
}

.about__gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

.about__photo {
  position: relative;
  overflow: hidden;
  margin: 0;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.about__photo img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .about__photo-fallback below (same
     position:absolute, no z-index) — otherwise the fallback text, later in
     source order, paints on top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about__photo-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.about__photo--main {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 9;
}

.about__gallery-sub {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

.about__photo--sub1 {
  aspect-ratio: 3 / 4;
}

.about__photo--sub2 {
  aspect-ratio: 1 / 1;
  align-self: end;
  margin-top: var(--space-lg);
}

/* Photos get a slightly heavier reveal treatment (more distance/blur, a
   touch of scale) than the generic text reveal above — still driven by the
   same [data-reveal]/--reveal-delay mechanism, just a more specific rule. */
.js .about__photo[data-reveal] {
  transform: translateY(36px) scale(0.98);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .about__photo[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ==========================================================================
   Service (#service) — scoped entirely under .section-service so it never
   affects the generic .section-content system still used by
   Policy/Works/Capabilities/Flow/etc.
   ========================================================================== */

.section-service {
  overflow: hidden;
}

.service__top {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-3xl);
}

.service__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.service__intro p + p {
  margin-top: var(--space-sm);
}

.service-item {
  position: relative;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: var(--space-2xl);
  align-items: center;
}

.service-item + .service-item {
  margin-top: var(--space-3xl);
  padding-top: var(--space-3xl);
  border-top: 1px solid var(--color-border);
}

.service-item--scaffolding {
  grid-template-columns: 0.85fr 1.15fr;
}

.service-item__media,
.service-item__content {
  position: relative;
  z-index: 1;
}

.service-item__media {
  position: relative;
  overflow: hidden;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.service-item__media img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .service-item__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s var(--ease-out);
}

/* Hover zoom is a PC/mouse-only flourish — never lock touch devices into a
   "hovered" state. */
@media (hover: hover) and (pointer: fine) {
  .service-item__media:hover img {
    transform: scale(1.025);
  }
}

.service-item__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.service-item--demolition .service-item__media {
  aspect-ratio: 16 / 11;
  margin-inline-start: calc(var(--container-pad) * -1);
}

.service-item--scaffolding .service-item__media {
  aspect-ratio: 1 / 1;
  margin-top: var(--space-lg);
}

.service-item__en {
  display: block;
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-green);
  margin-bottom: var(--space-sm);
}

.service-item__title {
  font-family: var(--font-heading);
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
}

.service-item__body {
  margin-top: var(--space-lg);
  max-width: 34rem;
}

.service-item__body p {
  color: var(--color-text);
  line-height: 1.9;
}

.service-item__body p + p {
  margin-top: var(--space-md);
}

.service-item__list {
  margin-top: var(--space-lg);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--space-lg);
  max-width: 34rem;
}

.service-item__list li {
  position: relative;
  padding-left: var(--space-md);
  padding-block: var(--space-2xs);
  font-size: var(--fs-small);
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
}

.service-item__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 12px;
  height: 1px;
  background-color: var(--color-green);
  transform: translateY(-50%);
}

.service-item__bg-text {
  position: absolute;
  z-index: 0;
  bottom: -0.12em;
  margin: 0;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: clamp(3rem, 7vw, 5.5rem);
  line-height: 1;
  opacity: 0.06;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.service-item--demolition .service-item__bg-text {
  right: 0;
  color: var(--color-green);
}

.service-item--scaffolding .service-item__bg-text {
  left: 0;
  color: var(--color-purple);
}

/* Photo reveal — same heavier treatment used for About's photos. */
.js .service-item__media[data-reveal] {
  transform: translateY(40px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .service-item__media[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ==========================================================================
   Policy (#policy) — scoped entirely under .section-policy so it never
   affects the generic .section-content system still used by
   Works/Capabilities/Flow/etc.
   ========================================================================== */

.section-policy {
  position: relative;
  overflow: hidden;
}

.policy__inner {
  position: relative;
}

.policy__bg-text {
  position: absolute;
  top: -0.1em;
  left: -0.03em;
  z-index: 0;
  margin: 0;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: clamp(6rem, 16vw, 13rem);
  line-height: 1;
  color: var(--color-text-sub);
  opacity: 0.05;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.policy__top {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-3xl);
}

.policy__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.policy__list {
  position: relative;
  z-index: 1;
  border-bottom: 1px solid var(--color-border);
}

.policy-item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(140px, 0.22fr) 1fr;
  column-gap: var(--space-2xl);
  align-items: center;
  padding-block: var(--space-2xl);
  border-top: 1px solid var(--color-border);
  transition: border-color 0.3s ease;
}

.policy-item--has-media {
  grid-template-columns: minmax(140px, 0.18fr) 1fr minmax(300px, 0.5fr);
}

/* 03 gets a deliberately smaller photo slot than 01/02, so the three
   photographed items don't all read as the same size/shape. */
.policy-item--03.policy-item--has-media {
  grid-template-columns: minmax(140px, 0.18fr) 1fr minmax(220px, 0.36fr);
}

/* 04 has no photo — give its number/heading/description a bit more room
   and presence so it reads as an intentional, spacious text-only close
   rather than a leftover empty slot. */
.policy-item:not(.policy-item--has-media) {
  padding-block: var(--space-3xl);
}

.policy-item:not(.policy-item--has-media) .policy-item__title {
  font-size: clamp(2rem, 3.4vw, 3.6rem);
}

.policy-item:not(.policy-item--has-media) .policy-item__description {
  max-width: 40rem;
  font-size: var(--fs-lead);
}

.policy-item__number {
  margin: 0;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: clamp(4rem, 8vw, 9rem);
  line-height: 1;
  /* Deliberately color (not opacity) for the "muted" resting look — this
     element also carries [data-reveal], whose own fade-in already animates
     opacity 0→1. Using opacity here too would fight that: as soon as the
     reveal completes, the generic .is-visible rule forces opacity:1 and
     silently wipes out this "faded number" styling. */
  color: rgba(125, 110, 178, 0.55);
  transition: color 0.3s ease;
}

.policy-item--02 .policy-item__number,
.policy-item--04 .policy-item__number {
  color: rgba(58, 142, 101, 0.55);
}

.policy-item__en {
  display: block;
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-sub);
  margin-bottom: var(--space-2xs);
}

.policy-item__title {
  display: inline-block;
  font-family: var(--font-heading);
  font-size: clamp(1.8rem, 3vw, 3.2rem);
  line-height: var(--lh-heading);
  transition: transform 0.3s var(--ease-out);
}

.policy-item__description {
  margin-top: var(--space-sm);
  max-width: 34rem;
  color: var(--color-text);
  line-height: 1.9;
}

.policy-item__media {
  position: relative;
  overflow: hidden;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
  aspect-ratio: 4 / 5;
}

.policy-item--02 .policy-item__media {
  aspect-ratio: 4 / 3;
}

.policy-item--03 .policy-item__media {
  aspect-ratio: 1 / 1;
  align-self: center;
}

.policy-item__media img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .policy-item__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.policy-item__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

/* Subtle PC-only hover — never lock touch devices into a "hovered" state. */
@media (hover: hover) and (pointer: fine) {
  .policy-item--01:hover,
  .policy-item--03:hover {
    border-top-color: var(--color-purple);
  }

  .policy-item--02:hover,
  .policy-item--04:hover {
    border-top-color: var(--color-green);
  }

  .policy-item--01:hover .policy-item__number,
  .policy-item--03:hover .policy-item__number {
    color: rgba(125, 110, 178, 0.85);
  }

  .policy-item--02:hover .policy-item__number,
  .policy-item--04:hover .policy-item__number {
    color: rgba(58, 142, 101, 0.85);
  }

  .policy-item:hover .policy-item__title {
    transform: translateX(6px);
  }
}

/* Photo reveal — same heavier treatment used for About's/Service's photos. */
.js .policy-item__media[data-reveal] {
  transform: translateY(36px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .policy-item__media[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ==========================================================================
   Works (#works) — scoped entirely under .section-works so it never
   affects the generic .section-content system still used by
   Capabilities/Flow/etc.
   ========================================================================== */

.works__top {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-2xl);
}

.works__top-right {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.works__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.works__intro p + p {
  margin-top: var(--space-sm);
}

.works-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.works-filter__btn {
  font-size: var(--fs-small);
  color: var(--color-text-sub);
  background-color: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: var(--space-2xs) var(--space-md);
  transition: color 0.3s ease, border-color 0.3s ease, background-color 0.3s ease;
}

.works-filter__btn:hover {
  color: var(--color-green);
  border-color: var(--color-green);
}

.works-filter__btn[aria-pressed="true"] {
  color: var(--color-green);
  border-color: var(--color-green);
  background-color: var(--color-green-soft);
}

/* Sub-category row (currently: demolition only) — deliberately smaller and
   quieter than the main category pills: a thin underline, no fill, no
   pill shape, so it never competes visually with the main row above it. */
.works-subfilter-group {
  margin-top: var(--space-xs);
}

.works-subfilter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.works-subfilter[hidden] {
  display: none;
}

.works-subfilter__btn {
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
  color: var(--color-text-sub);
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.works-subfilter__btn:hover {
  color: var(--color-purple);
}

.works-subfilter__btn[aria-pressed="true"] {
  color: var(--color-purple);
  border-bottom-color: var(--color-purple);
}

/* ---- Grid --------------------------------------------------------------- */

.works-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

.work-card {
  position: relative;
  transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}

/* Category-filter show/hide. Deliberately on the OUTER .work-card, never on
   .work-card__trigger (which carries [data-reveal] for the scroll-in
   animation) — two different elements, so the filter's opacity/transform
   never fights the reveal system's opacity/transform on the same node
   (the exact bug hit earlier with Policy's number color). */
.work-card.is-filtered-out {
  opacity: 0;
  transform: translateY(12px) scale(0.985);
  pointer-events: none;
}

.work-card__trigger {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.work-card__media {
  display: block;
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.work-card__media img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .work-card__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .work-card__trigger:hover .work-card__media img {
    transform: scale(1.025);
  }
}

.work-card__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.work-card__sample {
  position: absolute;
  top: var(--space-xs);
  left: var(--space-xs);
  z-index: 2;
  background-color: rgba(255, 255, 255, 0.88);
  color: var(--color-text-sub);
  font-family: var(--font-en);
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  padding: 3px 10px;
  border-radius: var(--radius-sm);
}

.work-card__info {
  display: block;
  margin-top: var(--space-sm);
}

.work-card__category {
  display: block;
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-sub);
  margin-bottom: var(--space-3xs);
  transition: color 0.3s ease;
}

/* Sub-category — smaller and quieter than the main category label above
   it, per spec ("サブカテゴリー表示は、メインカテゴリーより小さくして
   ください"). */
.work-card__subcategory {
  display: block;
  font-size: 0.7rem;
  color: var(--color-text-sub);
  opacity: 0.85;
  margin-bottom: var(--space-3xs);
}

.work-card__title {
  font-family: var(--font-ja);
  font-size: 1.15rem;
  line-height: 1.5;
}

.work-card__location {
  display: block;
  margin-top: var(--space-3xs);
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.work-card__view {
  display: inline-block;
  margin-top: var(--space-2xs);
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--color-text-sub);
  transition: color 0.3s ease;
}

.work-card__view::after {
  content: "→";
  margin-left: 4px;
}

@media (hover: hover) and (pointer: fine) {
  .work-card__trigger:hover .work-card__category,
  .work-card__trigger:hover .work-card__view {
    color: var(--color-green);
  }
}

/* PC-only bonus detail on hover — never relied on for the essentials
   (category/title stay visible unconditionally above). */
.work-card__hover {
  margin-top: var(--space-2xs);
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
  transition: max-height 0.3s ease, opacity 0.3s ease;
}

@media (hover: hover) and (pointer: fine) {
  .work-card__trigger:hover .work-card__hover {
    max-height: 100px;
    opacity: 1;
  }
}

.works-empty {
  grid-column: 1 / -1;
  padding-block: var(--space-3xl);
  text-align: center;
  font-size: var(--fs-lead);
  color: var(--color-text-sub);
}

.works-noscript-list {
  margin-top: var(--space-lg);
}

.works-noscript-list li {
  padding-block: var(--space-2xs);
  border-bottom: 1px solid var(--color-border);
}

/* Photo reveal — same heavier treatment used across About/Service/Policy. */
.js .work-card__trigger[data-reveal] {
  transform: translateY(40px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .work-card__trigger[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ---- Modal ---------------------------------------------------------------
   Static shell lives in index.html; works-modal.js only toggles classes /
   the hidden attribute and fills in text content.
   ========================================================================== */

.works-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-lg);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.works-modal[hidden] {
  display: none;
}

.works-modal.is-open {
  opacity: 1;
}

.works-modal__backdrop {
  position: absolute;
  inset: 0;
  background-color: rgba(32, 32, 32, 0.5);
}

.works-modal__dialog {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 720px;
  max-height: 88vh;
  background-color: var(--color-white);
  border-radius: var(--radius-sm);
  transform: translateY(16px);
  transition: transform 0.3s ease;
  overflow: hidden;
}

.works-modal.is-open .works-modal__dialog {
  transform: translateY(0);
}

.works-modal__close {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  z-index: 2;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--color-text);
  background-color: rgba(255, 255, 255, 0.85);
  border-radius: 50%;
}

.works-modal__close:hover {
  color: var(--color-green);
}

.works-modal__scroll {
  overflow-y: auto;
  min-height: 0;
}

.works-modal__media {
  position: relative;
  aspect-ratio: 16 / 10;
  background-color: #eae8e2;
}

.works-modal__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.works-modal__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.works-modal__fallback[hidden] {
  display: none;
}

.works-modal__body {
  padding: var(--space-xl);
}

.works-modal__category {
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-green);
}

.works-modal__subcategory {
  margin-top: var(--space-3xs);
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.works-modal__subcategory[hidden] {
  display: none;
}

.works-modal__title {
  margin-top: var(--space-2xs);
  margin-bottom: var(--space-md);
  font-family: var(--font-heading);
  font-size: 1.6rem;
}

.works-modal__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2xs) var(--space-lg);
  margin-bottom: var(--space-md);
}

.works-modal__meta dt {
  color: var(--color-text-sub);
  font-size: var(--fs-small);
}

.works-modal__description,
.works-modal__point {
  color: var(--color-text);
  line-height: 1.9;
}

.works-modal__point {
  margin-top: var(--space-sm);
}

/* Extra photos beyond the main image (work.gallery in site-data.js) — a
   simple wrapping row of equal-size thumbnails, not a carousel/lightbox.
   Hidden entirely via the `hidden` attribute when a work has no gallery
   (works-modal.js), so a single-photo entry never reserves empty space. */
.works-modal__gallery {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
}

.works-modal__gallery-image {
  width: calc(33.333% - var(--space-sm) * 2 / 3);
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background-color: #eae8e2;
}

/* ==========================================================================
   Capabilities (#capabilities) — scoped entirely under .section-capabilities
   so it never affects the generic .section-content system still used by
   Flow/etc. Deliberately NOT a repeat of Service's photo-beside-text
   layout: each capability is one vertical stack (photo → label → title →
   description → list), and the asymmetry instead comes from the outer
   58/42 column split plus the two very different photo aspect ratios.
   ========================================================================== */

.capabilities__top {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-3xl);
}

.capabilities__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.capabilities__intro p + p {
  margin-top: var(--space-sm);
}

.capabilities__content {
  display: grid;
  /* 解体工事は項目数が多いため少し広く（約58%/42%）。fr値なので画面幅に
     応じて自然に比率が保たれる。 */
  grid-template-columns: 58fr 42fr;
  gap: var(--space-2xl);
  align-items: start;
}

.capability {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.capability__media {
  display: block;
  position: relative;
  overflow: hidden;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.capability--demolition .capability__media {
  aspect-ratio: 16 / 10;
}

.capability--scaffolding .capability__media {
  aspect-ratio: 4 / 5;
}

.capability__media img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .capability__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.capability__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.capability__bg-text {
  position: absolute;
  z-index: 0;
  top: -0.1em;
  right: 0;
  margin: 0;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  line-height: 1;
  opacity: 0.06;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.capability--demolition .capability__bg-text {
  color: var(--color-purple);
}

.capability--scaffolding .capability__bg-text {
  color: var(--color-green);
}

.capability__body {
  position: relative;
  z-index: 1;
}

.capability__en {
  display: block;
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-green);
  margin-bottom: var(--space-sm);
}

.capability__title {
  font-family: var(--font-heading);
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
}

.capability__description {
  margin-top: var(--space-md);
  max-width: 34rem;
}

.capability__description p {
  color: var(--color-text);
  line-height: 1.9;
}

.capability__description p + p {
  margin-top: var(--space-sm);
}

.capability__list {
  margin-top: var(--space-lg);
  max-width: 34rem;
}

.capability__list li {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding-block: var(--space-2xs);
  border-bottom: 1px solid var(--color-border);
  transition: border-color 0.3s ease;
}

.capability__list-number {
  min-width: 1.8em;
  font-family: var(--font-en);
  font-weight: 600;
  font-size: var(--fs-small);
  /* Color (not opacity) for the muted resting look — these <li> also carry
     [data-reveal], whose own fade-in animates opacity 0→1; reusing opacity
     here too would fight that once revealed (the exact bug hit earlier
     with Policy's number styling). */
  transition: color 0.3s ease;
}

.capability--demolition .capability__list-number {
  color: rgba(125, 110, 178, 0.75);
}

.capability--scaffolding .capability__list-number {
  color: rgba(58, 142, 101, 0.75);
}

.capability__list-text {
  color: var(--color-text);
  transition: transform 0.3s var(--ease-out);
}

/* Subtle PC-only hover — never relied on for the essentials (the list is
   fully readable without it), and never locks touch devices into a
   "hovered" state. */
@media (hover: hover) and (pointer: fine) {
  .capability--demolition .capability__list li:hover {
    border-bottom-color: var(--color-purple);
  }

  .capability--scaffolding .capability__list li:hover {
    border-bottom-color: var(--color-green);
  }

  .capability--demolition .capability__list li:hover .capability__list-number {
    color: var(--color-purple);
  }

  .capability--scaffolding .capability__list li:hover .capability__list-number {
    color: var(--color-green);
  }

  .capability__list li:hover .capability__list-text {
    transform: translateX(4px);
  }
}

/* Photo reveal — same heavier treatment used across About/Service/Policy/
   Works. */
.js .capability__media[data-reveal] {
  transform: translateY(36px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .capability__media[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ==========================================================================
   Flow (#flow) — a vertical timeline, not a row of 7 equal cards. The big
   number is the focal point of each step; a single continuous line (plus a
   small dot per step) runs down the rail column to express "one connected
   process". Only 3 of 7 steps carry a photo, each a different size/ratio,
   so nothing here assumes every step has media.
   ========================================================================== */

.flow__top {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-3xl);
}

.flow__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.flow__intro p + p {
  margin-top: var(--space-sm);
}

.flow__list {
  --flow-rail: clamp(90px, 11vw, 160px);
  position: relative;
}

/* The continuous vertical line — always present (even with JS disabled or
   before a given step scrolls into view), so the "one connected process"
   reads immediately. Only each step's dot darkens on reveal. */
.flow__list::before {
  content: "";
  position: absolute;
  top: calc(var(--space-2xl) + 10px);
  bottom: calc(var(--space-2xl) + 10px);
  left: calc(var(--flow-rail) / 2 - 0.5px);
  width: 1px;
  background-color: var(--color-border);
  pointer-events: none;
}

.flow-step {
  position: relative;
  padding-block: var(--space-2xl);
}

/* Three columns — number / heading / body — so the title and description
   sit on the same visual row regardless of how tall the number is (a
   two-column "number+title stacked left, description right" layout looked
   mismatched: the description floated up next to the number instead of
   beside its title). */
.flow-step__content {
  display: grid;
  grid-template-columns: var(--flow-rail) minmax(180px, 300px) 1fr;
  column-gap: var(--space-xl);
  align-items: start;
}

.flow-step--purple {
  --flow-accent: var(--color-purple);
  --flow-accent-muted: rgba(125, 110, 178, 0.55);
}

.flow-step--green {
  --flow-accent: var(--color-green);
  --flow-accent-muted: rgba(58, 142, 101, 0.55);
}

.flow-step__dot {
  position: absolute;
  top: calc(var(--space-2xl) + 10px);
  left: calc(var(--flow-rail) / 2 - 5px);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: var(--color-border);
  z-index: 1;
}

/* Kept always-opaque (not gated behind the generic [data-reveal] opacity
   fade — same override technique used for Capabilities/Works media) so the
   line reads as continuous even before a step is reached; only its color
   darkens once revealed. */
.js .flow-step__dot[data-reveal] {
  opacity: 1;
  transform: none;
  filter: none;
  transition: background-color 0.4s ease;
  transition-delay: var(--reveal-delay, 0ms);
}

.js .flow-step__dot[data-reveal].is-visible {
  background-color: var(--flow-accent);
}

.flow-step__number {
  position: relative;
  z-index: 1;
  margin: 0;
  font-family: var(--font-en);
  font-weight: 700;
  font-size: clamp(4rem, 7vw, 8rem);
  line-height: 1;
  /* Color (not opacity) for the muted resting look — this element also
     carries [data-reveal], whose own fade-in animates opacity; reusing
     opacity here too would fight that once revealed. */
  color: var(--flow-accent-muted);
  transition: color 0.4s ease;
}

.js .flow-step__number[data-reveal].is-visible {
  color: var(--flow-accent);
}

.flow-step__en {
  margin: var(--space-sm) 0 var(--space-2xs);
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-sub);
}

.flow-step__title {
  margin: 0;
  font-family: var(--font-ja);
  font-size: clamp(1.5rem, 2.5vw, 2.7rem);
  line-height: var(--lh-heading);
  transition: transform 0.3s var(--ease-out);
}

.flow-step__body {
  padding-top: var(--space-2xs);
}

.flow-step__description {
  max-width: 34rem;
  color: var(--color-charcoal);
  line-height: 2;
}

.flow-step__media {
  display: block;
  position: relative;
  overflow: hidden;
  margin-top: var(--space-lg);
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.flow-step__media--compact {
  max-width: 320px;
  aspect-ratio: 16 / 10;
}

.flow-step__media--tall {
  max-width: 260px;
  aspect-ratio: 4 / 5;
}

.flow-step__media--wide {
  max-width: 480px;
  aspect-ratio: 16 / 9;
}

/* Optional second photo (item.image2) — same size as the first, placed
   side by side. Only used by steps that set image2 in site-data.js
   (currently 近隣対応・事前準備); every other step still renders a single
   .flow-step__media with no group wrapper. */
.flow-step__media-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-top: var(--space-lg);
}

.flow-step__media-group .flow-step__media {
  margin-top: 0;
  flex: 1 1 0;
}

.flow-step__media img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .flow-step__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.flow-step__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

/* Photo reveal — same heavier treatment used across About/Service/Policy/
   Works/Capabilities. */
.js .flow-step__media[data-reveal] {
  transform: translateY(36px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .flow-step__media[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* Subtle PC-only hover — never relied on for the essentials, never locks
   touch devices into a "hovered" state. */
@media (hover: hover) and (pointer: fine) {
  .flow-step:hover .flow-step__number {
    color: var(--flow-accent);
  }

  .flow-step:hover .flow-step__dot {
    background-color: var(--flow-accent);
  }

  /* Needs to out-specify ".js [data-reveal].is-visible" (which also sets
     transform, to "none", on this same element once revealed) — otherwise
     the generic reveal rule silently wins and the hover shift never shows. */
  .js .flow-step:hover .flow-step__title[data-reveal] {
    transform: translateX(4px);
  }
}

.flow-noscript-list {
  margin-top: var(--space-lg);
}

.flow-noscript-list li {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-block: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

.flow-noscript-list strong {
  font-weight: 600;
}

.flow-noscript-list span {
  color: var(--color-charcoal);
}

.flow__note {
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
  max-width: 40rem;
  font-size: var(--fs-small);
  line-height: 1.9;
  color: var(--color-text-sub);
}

.about__link.flow__cta-link {
  margin-top: var(--space-lg);
}

/* ==========================================================================
   Generic split content layout (text + media) — reused by every section
   below the hero. Each section keeps its own modifier class as a hook for
   later, section-specific redesign.
   ========================================================================== */

.section-content {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xl);
  margin-top: var(--space-xl);
}

.section-content__text,
.section-content__media {
  flex: 1 1 320px;
}

.section-content__media {
  min-height: 200px;
  background-color: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

/* Not yet populated with a photo (later phase) — collapse instead of
   reserving a large empty box. Stops still-empty sections from taking up
   an oversized amount of page height. */
.section-content__media:empty {
  min-height: 0;
  background-color: transparent;
  border: none;
}

/* ==========================================================================
   Company (#company) — a photo + Googleマップ用領域 on the left (~42%), and
   a read-like dl of confirmed company/license details on the right (~58%).
   Deliberately not a plain old-fashioned company table: generous spacing,
   a thin rule per row, and a restrained accent on the two license rows
   only (this is the trust-critical information on the page).
   ========================================================================== */

.company__top {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-2xl);
  align-items: center;
  margin-bottom: var(--space-3xl);
}

.company__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.company__intro p + p {
  margin-top: var(--space-sm);
}

.company__content {
  display: grid;
  /* Photo side is deliberately narrower than the profile list (~42/58),
     matching the ratio already used elsewhere for an asymmetric split. */
  grid-template-columns: 42fr 58fr;
  gap: var(--space-2xl);
  align-items: start;
}

.company__visual {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.company__image {
  display: block;
  position: relative;
  overflow: hidden;
  margin: 0;
  aspect-ratio: 4 / 5;
  background-color: #eae8e2;
  border-radius: var(--radius-sm);
}

.company__image img {
  position: absolute;
  inset: 0;
  /* Wins the stacking order over .company__fallback (same
     position:absolute, no z-index) — otherwise the fallback text paints on
     top of a successfully-loaded photo. */
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.company__fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

/* Photo reveal — same heavier treatment used across every other section. */
.js .company__image[data-reveal] {
  transform: translateY(36px) scale(0.985);
  filter: blur(5px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .company__image[data-reveal].is-visible {
  transform: translateY(0) scale(1);
  filter: blur(0);
}

.company-profile {
  display: flex;
  flex-direction: column;
}

.company-profile__row {
  display: grid;
  grid-template-columns: minmax(120px, 180px) 1fr;
  column-gap: var(--space-lg);
  padding-block: var(--space-md);
  border-bottom: 1px solid var(--color-border);
  transition: border-color 0.3s ease;
}

.company-profile__row dt {
  color: var(--color-text-sub);
  font-size: var(--fs-small);
}

.company-profile__row dd {
  color: var(--color-text);
  overflow-wrap: break-word;
  transition: transform 0.3s var(--ease-out);
}

.company-profile__row a {
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
  transition: color 0.3s ease, border-color 0.3s ease;
}

.company-profile__row a:hover,
.company-profile__row a:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

.company-profile__row--license dd p + p {
  margin-top: var(--space-3xs);
}

/* A thin accent rule on the two license rows only — this is the
   trust-critical information, so it gets a small, restrained callout
   rather than a badge or heavier decoration. */
.company-profile__row--license {
  border-left: 2px solid transparent;
  padding-left: var(--space-md);
}

.company-profile__row--purple {
  border-left-color: var(--color-purple-soft);
}

.company-profile__row--green {
  border-left-color: var(--color-green-soft);
}

/* Subtle PC-only hover — never relied on for the essentials, never locks
   touch devices into a "hovered" state. */
@media (hover: hover) and (pointer: fine) {
  .company-profile__row:hover dt {
    color: var(--color-text);
  }

  .company-profile__row--purple:hover {
    border-left-color: var(--color-purple);
  }

  .company-profile__row--green:hover {
    border-left-color: var(--color-green);
  }

  .company-profile__row:hover dd {
    transform: translateX(2px);
  }
}

/* ==========================================================================
   Contact (#contact) — guidance (~38%) on the left, form (~62%) on the
   right. Deliberately restrained: no red buttons, no urgency copy, a
   single quiet notice line rather than a banner for status/errors.
   ========================================================================== */

.contact__layout {
  display: grid;
  grid-template-columns: 38fr 62fr;
  gap: var(--space-2xl);
  align-items: start;
}

.contact__information {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  position: sticky;
  top: calc(var(--header-height) + var(--space-xl));
}

/* The base --fs-h2 clamp (up to 3rem) wraps "工事に関するご相談" onto a
   second line inside this column — at 38% of content-width it's much
   narrower than the columns every other section's heading sits in, and
   that column doesn't narrow in simple proportion to the viewport (it
   shrinks fastest just above the 768px breakpoint, then plateaus once
   content-width hits its 1240px cap). A single fixed size, sized for the
   tightest case just above that breakpoint, is simpler and safer here
   than a vw-based clamp. Reset back to --fs-h2 below 768px in
   responsive.css, where the single-column layout gives it full width. */
.contact__heading .section-heading__ja {
  font-size: 1.6rem;
}

.contact__intro p {
  color: var(--color-text);
  line-height: 1.9;
}

.contact__intro p + p {
  margin-top: var(--space-sm);
}

.contact__telephone {
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

.contact__telephone-label {
  font-size: var(--fs-small);
  color: var(--color-text-sub);
  margin-bottom: var(--space-2xs);
}

.contact__telephone-number {
  display: inline-block;
  font-family: var(--font-en);
  font-size: clamp(1.4rem, 1.8vw, 1.8rem);
  font-weight: 600;
  color: var(--color-text);
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.contact__telephone-hours {
  margin-top: var(--space-2xs);
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

@media (hover: hover) and (pointer: fine) {
  .contact__telephone-number:hover {
    color: var(--color-green);
    border-bottom-color: var(--color-green);
  }
}

.contact__telephone-number:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

/* Form
   ------------------------------------------------------------------------ */

.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.contact-form__row--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
}

.contact-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.contact-form__field label {
  font-size: var(--fs-small);
  color: var(--color-text);
}

.contact-form__required {
  margin-left: var(--space-2xs);
  color: var(--color-purple);
  font-size: var(--fs-micro);
  font-weight: 600;
}

.contact-form__optional {
  margin-left: var(--space-2xs);
  color: var(--color-text-sub);
  font-size: var(--fs-micro);
}

.contact-form__field input[type="text"],
.contact-form__field input[type="tel"],
.contact-form__field input[type="email"],
.contact-form__field select,
.contact-form__field textarea {
  /* width:100% + min-width:0 — without these, a <select>/<input> in a flex
     or grid container falls back to its own content-driven intrinsic width
     (for <select>, based on its longest <option> text) instead of shrinking
     to fit, which can force the whole column wider than its container once
     the base font size is large enough to push that intrinsic width past
     the available space. */
  width: 100%;
  min-width: 0;
  min-height: 48px;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: var(--color-white);
  font-family: var(--font-ja);
  font-size: var(--fs-body);
  color: var(--color-text);
  transition: border-color 0.3s ease;
}

.contact-form__field textarea {
  min-height: 160px;
  resize: vertical;
}

.contact-form__field input:focus-visible,
.contact-form__field select:focus-visible,
.contact-form__field textarea:focus-visible {
  outline: none;
  border-color: var(--color-purple);
  box-shadow: 0 0 0 2px var(--color-purple-soft);
}

.contact-form__field input[aria-invalid="true"],
.contact-form__field select[aria-invalid="true"],
.contact-form__field textarea[aria-invalid="true"] {
  border-color: var(--color-error);
}

.contact-form__hint {
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

/* input[type="file"] renders a native OS "choose file" button + filename
   text whose combined content the browser won't shrink below by default —
   same overflow risk as <select>, so it needs the same explicit
   width/min-width override to stay inside its container. */
.contact-form__field input[type="file"] {
  display: block;
  width: 100%;
  min-width: 0;
  max-width: 100%;
}

.contact-form__error {
  font-size: var(--fs-small);
  color: var(--color-error);
}

.contact-form__field--checkbox {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  column-gap: var(--space-sm);
}

.contact-form__field--checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--color-green);
}

.contact-form__field--checkbox label {
  grid-column: 2;
}

.contact-form__field--checkbox .contact-form__error {
  grid-column: 2;
}

.contact-form__field--checkbox a {
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
  transition: color 0.3s ease, border-color 0.3s ease;
}

.contact-form__field--checkbox a:hover,
.contact-form__field--checkbox a:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

/* File attachment
   ------------------------------------------------------------------------ */

.contact-form__file-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-top: var(--space-sm);
}

.contact-form__file-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
}

.contact-form__file-name {
  overflow-wrap: anywhere;
}

.contact-form__file-remove {
  flex-shrink: 0;
  font-size: var(--fs-micro);
  color: var(--color-text-sub);
  border-bottom: 1px solid var(--color-border);
  transition: color 0.3s ease, border-color 0.3s ease;
}

.contact-form__file-remove:hover,
.contact-form__file-remove:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

/* Honeypot — visually hidden without display:none/visibility:hidden (which
   some screen readers still announce inconsistently) and additionally
   pulled out of the tab order, so it never trips up keyboard users. */
.contact-form__honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Submit
   ------------------------------------------------------------------------ */

.contact-form__submit-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-lg);
}

.contact-form__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--space-sm) var(--space-2xl);
  border-radius: var(--radius-sm);
  background-color: var(--color-charcoal);
  color: var(--color-white);
  font-family: var(--font-en);
  font-size: var(--fs-small);
  letter-spacing: 0.04em;
  transition: background-color 0.3s ease;
}

@media (hover: hover) and (pointer: fine) {
  .contact-form__submit:hover:not(:disabled) {
    background-color: var(--color-green);
  }
}

.contact-form__submit:focus-visible {
  outline: 2px solid var(--color-purple);
  outline-offset: 2px;
}

.contact-form__submit:disabled {
  background-color: var(--color-border);
  color: var(--color-text-sub);
  cursor: not-allowed;
}

.contact-form__notice {
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

.contact-form__notice--success {
  color: var(--color-green);
}

.contact-form__notice--error {
  color: var(--color-error);
}

.contact-form__noscript {
  margin-top: var(--space-lg);
  font-size: var(--fs-small);
  color: var(--color-text-sub);
}

/* ==========================================================================
   Capabilities lists
   ========================================================================== */

.capability-group + .capability-group {
  margin-top: var(--space-lg);
}

.capability-group__title {
  font-size: var(--fs-lead);
  margin-bottom: var(--space-sm);
}

.capability-group__list li {
  padding-block: var(--space-3xs);
  border-bottom: 1px solid var(--color-border);
}

/* ==========================================================================
   Legal pages (privacy.html)
   ========================================================================== */

.legal-back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: var(--space-lg);
  color: var(--color-text-sub);
  font-size: var(--fs-small);
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.legal-back-link:hover,
.legal-back-link:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

.legal-body {
  max-width: 760px;
  margin-top: var(--space-xl);
}

.legal-body h2 {
  font-size: 1.25rem;
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-sm);
}

.legal-body h2:first-child {
  margin-top: 0;
}

.legal-body p {
  margin-bottom: var(--space-sm);
}

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

.site-footer {
  background-color: var(--color-charcoal);
  color: rgba(255, 255, 255, 0.75);
  padding-block: var(--space-3xl) var(--space-lg);
}

.site-footer__top {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xl);
  justify-content: space-between;
}

.site-footer__brand img {
  height: 36px;
  width: auto;
  margin-bottom: var(--space-md);
}

.site-footer__brand p {
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, 0.65);
}

.site-footer__brand p + p {
  margin-top: var(--space-2xs);
}

.site-footer__name {
  color: var(--color-white);
  font-size: var(--fs-body);
  font-weight: 600;
}

.site-footer__name-en {
  font-family: var(--font-en);
  color: rgba(255, 255, 255, 0.55);
}

.site-footer__brand a {
  color: rgba(255, 255, 255, 0.85);
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.site-footer__brand a:hover,
.site-footer__brand a:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

.site-footer__nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
}

.site-footer__nav a {
  color: rgba(255, 255, 255, 0.75);
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.site-footer__nav a:hover,
.site-footer__nav a:focus-visible {
  color: var(--color-white);
  border-bottom-color: var(--color-purple);
}

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-top: var(--space-2xl);
  padding-top: var(--space-md);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--fs-micro);
  color: rgba(255, 255, 255, 0.55);
}

.site-footer__totop {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  color: rgba(255, 255, 255, 0.7);
  font-family: var(--font-en);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.site-footer__totop:hover,
.site-footer__totop:focus-visible {
  color: var(--color-green);
  border-bottom-color: var(--color-green);
}

/* Fixed "back to top" button — hidden by default (no ".js" gate needed,
   since it only ever becomes visible via a class navigation.js adds; if JS
   never runs, it simply never appears, and the plain-anchor
   .site-footer__totop link above still works with zero JS). Faded via
   opacity/visibility rather than the `hidden` attribute so it can
   transition smoothly, and reduced-motion is already handled globally by
   reset.css (transition-duration forced near-zero). */
.back-to-top {
  position: fixed;
  right: var(--space-lg);
  bottom: var(--space-lg);
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 52px;
  height: 52px;
  background-color: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(8px);
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease,
    transform 0.3s ease,
    border-color 0.3s ease,
    color 0.3s ease;
}

.back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
}

.back-to-top__arrow {
  font-size: 1.1rem;
  line-height: 1;
}

.back-to-top__label {
  font-family: var(--font-en);
  font-size: 0.6rem;
  letter-spacing: 0.08em;
}

@media (hover: hover) and (pointer: fine) {
  .back-to-top:hover {
    border-color: var(--color-green);
    color: var(--color-green);
  }
}

.back-to-top:focus-visible {
  outline: 2px solid var(--color-purple);
  outline-offset: 2px;
}

/* Development-only indicator (assets/js/site-mode.js). Bottom-left — the
   back-to-top button already owns bottom-right, so the two never collide.
   Purely informational: no interaction, never intercepts clicks/taps. */
.dev-mode-badge {
  position: fixed;
  left: var(--space-md);
  bottom: var(--space-md);
  z-index: 40;
  margin: 0;
  padding: 4px 10px;
  background-color: rgba(60, 60, 60, 0.85);
  color: var(--color-white);
  font-family: var(--font-en);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  border-radius: var(--radius-sm);
  pointer-events: none;
}

/* ==========================================================================
   Scroll reveal (common processing)

   Default (no JS, or JS failed/blocked — e.g. ES modules do not run under
   file:// in most browsers): every [data-reveal] element is fully visible.
   Only once scroll-animation.js actually starts running does it add a "js"
   class to <html> itself — that is the ONLY thing that switches these
   elements to their hidden/animate-in state. If the script never runs, this
   rule is never reached and nothing stays stuck invisible.
   ========================================================================== */

[data-reveal] {
  opacity: 1;
  transform: none;
  filter: none;
}

.js [data-reveal] {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  filter: blur(4px);
  transition:
    opacity var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out),
    filter var(--duration-base) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform, filter;
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  filter: blur(0);
}

/* ==========================================================================
   Hero reveal (separate from the generic [data-reveal] scroll system above)

   The hero sits in the viewport from the very first frame, so its reveal
   can't be left to "scroll into view" — it must be sequenced by intro.js
   right as the intro overlay finishes (or is skipped/never shown). Same
   default-visible-unless-.js-is-present safety net applies.
   ========================================================================== */

.hero-reveal {
  opacity: 1;
  transform: none;
  filter: none;
}

.js .hero-reveal {
  opacity: 0;
  transform: translateY(24px);
  filter: blur(3px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    filter 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .hero-reveal.is-visible {
  opacity: 1;
  transform: none;
  filter: blur(0);
}

/* Header nav fading in as part of the post-intro reveal sequence — opacity
   only (no transform), so it never fights the off-canvas transform already
   applied to .site-nav on mobile (see responsive.css). */
.intro-nav-reveal {
  opacity: 1;
}

.js .intro-nav-reveal {
  opacity: 0;
  transition: opacity 0.6s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .intro-nav-reveal.is-visible {
  opacity: 1;
}

/* ==========================================================================
   Intro overlay

   Hidden by default (display:none) so a browser that never runs intro.js —
   JS disabled, blocked under file://, or a thrown error — never shows it at
   all; the page just renders the header/hero underneath normally. Only
   intro.js's own successful startup adds `.intro--active` to switch it on.
   ========================================================================== */

.intro {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
  align-items: center;
  justify-content: center;
}

.intro--active {
  display: flex;
}

.intro__bg {
  position: absolute;
  inset: 0;
  background-color: var(--color-white);
  transition: opacity 0.8s ease;
}

.intro__bg--out {
  opacity: 0;
}

.intro__logo-wrap {
  position: relative;
  width: clamp(220px, 30vw, 340px);
  opacity: 0;
  filter: blur(12px);
  transform: translateY(20px) scale(0.94);
  transition: opacity 1.2s var(--ease-out) 0.3s, filter 1.2s var(--ease-out) 0.3s,
    transform 1.2s var(--ease-out) 0.3s;
}

.intro__logo-wrap.is-in {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0) scale(1);
}

.intro__logo-wrap.is-moving {
  /* transform/opacity for the move-to-header step are set inline by
     intro.js (measured against the real header logo position), with their
     own transition declared there so the two don't fight. */
  transition: transform 0.7s var(--ease-out), opacity 0.6s var(--ease-out) 0.1s;
}

.intro__logo {
  display: block;
  width: 100%;
  height: auto;
}

.intro__flower-glow {
  position: absolute;
  left: 72%;
  top: 36%;
  width: 18%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) scale(0.6);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(circle, var(--color-purple-soft) 0%, var(--color-green-soft) 60%, transparent 75%);
}

.intro__flower-glow.is-pulsing {
  animation: intro-flower-pulse 0.6s var(--ease-out) 1;
}

@keyframes intro-flower-pulse {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.6);
  }
  45% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.25);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.4);
  }
}

.intro__skip {
  position: absolute;
  right: var(--space-lg);
  bottom: var(--space-lg);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--color-text-sub);
  padding: var(--space-2xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: rgba(255, 255, 255, 0.6);
}

.intro__skip:hover,
.intro__skip:focus-visible {
  color: var(--color-green);
  border-color: var(--color-green);
}

/* The real header logo stays invisible (but present/laid out) while the
   intro is playing, and fades in exactly as the intro logo fades out —
   selling the "moved to the header" illusion without true FLIP reparenting. */
.intro-playing .site-header__logo {
  opacity: 0;
}

.site-header__logo {
  transition: opacity 0.6s var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .intro__logo-wrap,
  .intro__bg,
  .site-header__logo {
    transition: none !important;
  }
}
