/* ============================================================
   Tokens
   ============================================================ */
:root{
  --bg:#f3f2ef;
  --bg-sub:#e9e8e4;
  --fg:#141414;
  --fg-dim:#6d6d69;
  --line:rgba(0,0,0,.14);
  --line-strong:rgba(0,0,0,.3);
  --card:#e6e5e1;
  --accent:#333331;      /* fills: dots, buttons, pins */
  --accent-ink:#4a4a47;  /* the same hue, legible as text on --bg */
  --on-accent:#f3f2ef;   /* text/icons sitting on an --accent fill */
  --r-btn:8px;           /* buttons */
  --r-icon:6px;          /* small icon squares inside buttons */
  --ease:cubic-bezier(.22,1,.36,1);
  --pad:clamp(20px,5vw,80px);
  --maxw:1560px;
}

/* Page-to-page crossfade, JS-driven (see assets/app.js): a full-viewport
   plate that covers the page on load and on the way out to another page.
   The *resting* (no-class) state has to be the covering one — opaque, at
   translateY(0) — because that's what's on screen for the brief window
   between HTML parsing and app.js actually running; anything else is a
   flash of the real page underneath before JS ever gets a chance to hide
   it. .revealing (added once app.js does run) has to start from that exact
   same transform for the same reason. .covering (added on an outbound
   click) reverses the same keyframe rather than defining its own,
   guaranteeing it always starts from wherever .revealing actually left the
   plate, whatever that turns out to be, instead of assuming a fixed value.
   Duration here has to match app.js's FADE_MS. */
.page-fade{position:fixed;inset:0;z-index:9999;background:var(--bg);
  transform:translateY(0);pointer-events:none}
.page-fade.covering{animation:slideCover .7s cubic-bezier(.4,0,.2,1) reverse forwards}
.page-fade.revealing{animation:slideCover .7s cubic-bezier(.4,0,.2,1) forwards}
@keyframes slideCover{from{transform:translateY(0)}to{transform:translateY(-100%)}}
/* The SWG mark, centered and held smaller than the intro's own 300px — the
   plate is only up for .7s, no room for a zoom. Drawn as flying-in/out
   square grains rather than a static image, the same technique as the hero
   title (see startHeroTitle in app.js), just sourced from the mark shape
   instead of glyphs: assembles as the plate covers the outgoing page,
   disperses as it uncovers the incoming one. */
.page-fade-mark{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  pointer-events:none}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Always reserve the scrollbar. The intro locks scrolling on load, so without
   this the page starts with no scrollbar and the horizontal track measures a
   viewport that is about to get narrower. */
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;overflow-y:scroll}
body{
  background:var(--bg);color:var(--fg);
  font-family:"futura-pt","Noto Sans JP","Yu Gothic",YuGothic,"Hiragino Kaku Gothic Pro",sans-serif;
  font-feature-settings:"palt" 1;
  line-height:1.75;letter-spacing:.02em;
  /* `clip`, not `hidden` — hidden turns body into a scroll container, which
     silently kills the position:sticky pin the horizontal track depends on. */
  overflow-x:clip;
}
a{color:inherit;text-decoration:none}
li{list-style:none}
img{max-width:100%;display:block}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--fg);color:var(--bg)}

.en{font-family:"futura-pt",sans-serif;letter-spacing:.06em}
.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--pad)}

/* ============================================================
   Intro
   ============================================================ */
/* A full-screen plate of the hero footage, revealed only through the SWG
   mark. The mask grows until the shape is far larger than the viewport, at
   which point the plate is indistinguishable from the hero behind it and the
   whole overlay lifts. The footage settles from a slight push-in so the cut
   to the hero reads as one continuous shot. */
.intro{position:fixed;inset:0;z-index:300;background:var(--bg);overflow:hidden;
    animation:introOut .5s var(--ease) 3s forwards}
/* The mark is filled with a mid tone and the footage rides on top of it at
   partial opacity. The clip swings from near-black to near-white, and on its
   own either extreme kills the shape — black crushes the texture away, white
   dissolves into the page. The backing plate keeps the mark legible at every
   frame while still letting the movement read through. It fades out as the
   zoom takes over, leaving the footage on the hero's exact treatment. */
.intro-clip{position:absolute;inset:0;opacity:0;background:#8e8c86;
    -webkit-mask:url(mark.svg) no-repeat center;mask:url(mark.svg) no-repeat center;
    -webkit-mask-size:300px auto;mask-size:300px auto;
    animation:introZoom 3.1s forwards, introBacking 3.1s forwards}
/* Same -90° rotation and vh/vw dimension swap as the hero's copy of this
   footage — see the note on .hero-video. The settle-zoom (scale) rides
   alongside it in the same transform, animated in introSettle below. */
.intro-video{position:absolute;top:50%;left:50%;
    width:100vh;height:100vw;max-width:none;
    object-fit:cover;
    filter:grayscale(1) brightness(1.3) contrast(1.15);opacity:.9;
    transform:translate(-50%,-50%) rotate(-90deg) scale(1.16);
    animation:introSettle 3.1s linear forwards}
.intro-video::-webkit-media-controls-start-playback-button{display:none!important;opacity:0!important;pointer-events:none!important}

/* Dead still on 300px for the first two seconds — the mark just sits there
   with the footage moving inside it — then one uninterrupted acceleration
   out to a size far past every edge of the viewport. */
@keyframes introZoom{
  0%   {opacity:0;-webkit-mask-size:300px auto;mask-size:300px auto}
  12%  {opacity:1;-webkit-mask-size:300px auto;mask-size:300px auto}
  64.5%{opacity:1;-webkit-mask-size:300px auto;mask-size:300px auto;
        animation-timing-function:cubic-bezier(.66,0,.86,.28)}
  100% {opacity:1;-webkit-mask-size:34000px auto;mask-size:34000px auto}
}
/* Runs on its own track so the backing can be gone well before the overlay
   hands over — otherwise a sheet of grey would still be sitting over the
   footage at the crossfade. */
@keyframes introBacking{
  0%,64.5%{background-color:#8e8c86}
  84%,100%{background-color:transparent}
}
@keyframes introSettle{
  0%   {transform:translate(-50%,-50%) rotate(-90deg) scale(1.16);filter:grayscale(1) brightness(1.3) contrast(1.15);opacity:.9}
  64.5%{transform:translate(-50%,-50%) rotate(-90deg) scale(1.1);filter:grayscale(1) brightness(1.3) contrast(1.15);opacity:.9}
  100% {transform:translate(-50%,-50%) rotate(-90deg) scale(1);filter:grayscale(1) brightness(1.7) contrast(1.05);opacity:.75}
}
@keyframes introOut{to{opacity:0;visibility:hidden}}

/* Hold the page still, and hold the hero's own entrance, until the intro is
   done — otherwise the headline plays out behind the overlay. */
body.intro-on{overflow:hidden}
body.intro-on .hero-kw,
body.intro-on .hero-foot{animation-play-state:paused}
body.intro-done .intro{display:none}

/* ============================================================
   Header
   ============================================================ */
.hd{position:fixed;inset:0 0 auto 0;z-index:100;padding:0 var(--pad);
    display:flex;align-items:center;justify-content:space-between;height:84px;
    mix-blend-mode:normal}
.hd::before{content:"";position:absolute;inset:0;backdrop-filter:blur(14px);
    background:color-mix(in srgb,var(--bg) 62%,transparent);
    opacity:0;transition:opacity .4s var(--ease);z-index:-1}
.hd.stuck::before{opacity:1}

.logo{display:inline-flex;align-items:center}
.logo img{height:64px;width:auto;transition:opacity .35s var(--ease)}
a.logo:hover img{opacity:.6}

.hd-right{display:flex;align-items:center;gap:14px}

.btn-contact{border:1px solid var(--line-strong);border-radius:var(--r-btn);padding:9px 34px;
    font-size:15px;letter-spacing:.14em;position:relative;overflow:hidden;isolation:isolate}
.btn-contact span{position:relative;z-index:1;transition:color .45s var(--ease)}
.btn-contact::before{content:"";position:absolute;inset:0;background:var(--accent);
    transform:translateY(101%);transition:transform .5s var(--ease);z-index:0}
.btn-contact:hover::before{transform:translateY(0)}
.btn-contact:hover span{color:var(--on-accent)}

.burger{width:44px;height:44px;border:1px solid var(--line);border-radius:var(--r-btn);
    display:grid;place-content:center;gap:5px;transition:.35s var(--ease)}
.burger i{display:block;width:15px;height:1px;background:var(--fg);transition:.4s var(--ease)}
.burger:hover{background:var(--fg)}
.burger:hover i{background:var(--bg)}
body.nav-open .burger i:first-child{transform:translateY(3px) rotate(45deg)}
body.nav-open .burger i:last-child{transform:translateY(-3px) rotate(-45deg)}

/* Nav overlay — sized to fit every item on one screen, with no internal
   scroll. The top padding clears the fixed header (which stays above the
   overlay, z-index 100 > 99) so the first row can never end up behind the
   logo. Row height comes from an implicit 1fr grid, so it divides whatever
   space is left evenly regardless of item count; typography is driven off
   vh, not vw, so it shrinks on short screens instead of overflowing. */
/* clip-path alone hid this (the 0-height inset at the top leaves nothing
   *supposed* to be visible), but that's still a fully laid-out, opacity:1
   element sitting over the whole viewport — rendering-precision rounding
   at the clip edge could leave a sliver of its own background showing
   right at the top. opacity/pointer-events are a hard backstop: instant,
   not animated, so the clip-path transition still carries the actual
   "unroll from the top" reveal. */
.nav{position:fixed;inset:0;z-index:99;background:var(--bg-sub);
    clip-path:inset(0 0 100% 0);transition:clip-path .8s var(--ease);
    display:flex;flex-direction:column;
    padding:calc(84px + clamp(14px,3vh,28px)) var(--pad) clamp(14px,3vh,28px);
    overflow:hidden;opacity:0;pointer-events:none}
body.nav-open .nav{clip-path:inset(0 0 0 0);opacity:1;pointer-events:auto}
body.nav-open{overflow:hidden}
/* Flex, not grid: every row shares the leftover space equally (flex:1,
   same effect as the old grid-auto-rows:1fr), but once the Service row
   opens it switches to flex:0 0 auto (its own content height) and the
   other 7 keep splitting whatever's left — so the list stays visually
   "full height" instead of every row snapping to single-line content
   height and leaving a gap at the bottom. min-height:100% (not a fixed
   height) plus overflow-y:auto lets it scroll if that no longer fits. */
.nav ol{display:flex;flex-direction:column;max-width:var(--maxw);margin-inline:auto;
    width:100%;min-height:100%;overflow-y:auto}
.nav > ol > li{border-top:1px solid var(--line);overflow:hidden;display:flex;
    flex:1 1 0;min-height:56px}
.nav > ol > li:last-child{border-bottom:1px solid var(--line)}
.nav > ol > li.nav-svc{flex-direction:column;align-items:stretch;justify-content:center}
.nav > ol > li.nav-svc.open{flex:0 0 auto}
.nav a{width:100%;display:flex;align-items:center;gap:clamp(14px,3vw,40px);
    transform:translateY(110%);transition:transform .7s var(--ease),padding-left .5s var(--ease)}
body.nav-open .nav a{transform:translateY(0)}
.nav a:hover{padding-left:20px}
.nav .idx{font-size:10px;color:var(--fg-dim);letter-spacing:.1em;min-width:26px}
.nav .en-l{font-size:clamp(18px,4.6vh,64px);font-weight:600;line-height:1;letter-spacing:-.01em}
.nav .ja-l{font-size:clamp(9px,1.5vh,11px);color:var(--fg-dim);letter-spacing:.16em}
.nav .arrow{margin-left:auto;opacity:0;transform:translateX(-14px);transition:.45s var(--ease);font-size:20px}
.nav a:hover .arrow{opacity:1;transform:translateX(0)}

.nav-svc-toggle{all:unset;box-sizing:border-box;width:100%;display:flex;align-items:center;
    gap:clamp(14px,3vw,40px);cursor:pointer;padding-block:clamp(16px,2.6vh,26px);
    transform:translateY(110%);transition:transform .7s var(--ease),padding-left .5s var(--ease)}
body.nav-open .nav-svc-toggle{transform:translateY(0)}
.nav-svc-toggle:hover{padding-left:20px}
.nav-caret{font-size:14px;color:var(--fg-dim);transition:transform .4s var(--ease)}
.nav-svc.open .nav-caret{transform:rotate(180deg)}
/* max-height is set to the panel's real scrollHeight in JS on toggle —
   inside this nested flex/overflow:hidden ancestry a grid 0fr→1fr track
   has no indefinite height to resolve "auto" against, so it never grows. */
.nav-svc-panel{max-height:0;overflow:hidden;transition:max-height .45s var(--ease)}
.nav-svc-sub{list-style:none;display:flex;flex-direction:column;gap:2px;padding:2px 0 16px}
.nav-svc-sub a{display:block;width:auto;padding:7px 0 7px calc(26px + clamp(14px,3vw,40px));
    font-size:13px;letter-spacing:.05em;color:var(--fg-dim);
    transform:none;transition:color .3s var(--ease),padding-left .3s var(--ease)}
.nav-svc-sub a:hover{color:var(--fg);padding-left:calc(26px + clamp(14px,3vw,40px) + 6px)}

/* ============================================================
   Hero
   ============================================================ */
.hero{min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;
      padding:120px var(--pad) clamp(30px,5vw,60px);position:relative;overflow:hidden}
/* Cloud loop behind the hero. The page runs on a light palette with dark
   type, so the footage is lightened and a scrim is laid over the lower half
   where the headline and lead sit. */
.hero-media{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--bg-sub)}
/* This footage (falling sand/dust against near-black) is already dark and
   close to monochrome — unlike the old clip, it needs lifting, not
   darkening. grayscale still guarantees no stray color cast; the brightness
   push is what actually makes the grain read against the page. */
/* Footage is shot portrait (particles falling straight down); rotated -90°
   so the fall reads as drifting in from the left instead. Rotating swaps
   the video's own visual width/height, so it's sized to 100vh × 100vw
   (the swap, ahead of the rotation) rather than 100% × 100% — sizing it to
   the container as-is would leave it fitting the *unrotated* box, which
   after the turn no longer matches the container at all. */
.hero-video{position:absolute;top:50%;left:50%;
    width:100vh;height:100vw;max-width:none;
    transform:translate(-50%,-50%) rotate(-90deg);
    object-fit:cover;display:block;
    filter:grayscale(1) brightness(1.7) contrast(1.05);opacity:.75}
.hero-scrim{position:absolute;inset:0;
  background:linear-gradient(to top,
      rgba(0,0,0,.5) 0%,
      rgba(0,0,0,.32) 26%,
      rgba(0,0,0,.14) 58%,
      transparent 100%)}
.grid-lines{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:calc(100%/6) 100%;opacity:.5}
.hero-inner{position:relative;z-index:2;max-width:var(--maxw);margin-inline:auto;width:100%}
/* The real h1 (see index.html) — a small kicker line, not the visual focus,
   so it sits quietly above the "No Excuse" headline instead of competing
   with it. */
.hero-brand{font-size:12px;font-weight:600;letter-spacing:.28em;
    color:rgba(255,255,255,.72);margin-bottom:clamp(10px,1.6vh,18px)}
.hero-headline{position:relative;font-size:clamp(34px,8.4vw,128px);line-height:.92;font-weight:600;letter-spacing:-.025em;color:#fff}
.hero-headline .ln{display:block;overflow:hidden}
/* Kept in the DOM for accessibility/SEO only — the particle canvas below is
   the permanent visual. app.js sets this to opacity:1 directly (no canvas)
   under reduced motion or if the canvas setup fails. */
.hero-headline .ln>span{display:block;opacity:0}
.hero-headline em{font-style:normal}
/* Sits over the (invisible) real text, sized to the measured label rather
   than h1's own box — see "hero title: particle assembly" in app.js. Takes
   pointer events itself (rather than staying pass-through) so it can track
   the mouse for the hover-blur spotlight; nothing else sits behind it. */
.hero-title-cv{position:absolute;left:0;top:0;cursor:default}
.hero-kw{margin-top:clamp(20px,2.8vw,38px);display:grid;gap:clamp(5px,.6vw,9px);
    opacity:0;animation:fade 1s var(--ease) .6s forwards}
.hero-kw li{display:flex;align-items:center;
    font-size:clamp(12px,1.15vw,16px);font-weight:500;letter-spacing:.22em;color:rgba(255,255,255,.72)}
.hero-foot{display:flex;flex-wrap:wrap;gap:24px;justify-content:space-between;align-items:flex-end;
    margin-top:clamp(28px,4vw,52px);opacity:0;animation:fade 1s var(--ease) .8s forwards}
@keyframes fade{to{opacity:1}}
.hero-foot>div:first-child{flex:1 1 420px}
.hero-foot p{font-size:13px;letter-spacing:.3em;color:rgba(255,255,255,.72)}
.hero-foot .lead{font-size:13px;letter-spacing:.04em;line-height:2;color:rgba(255,255,255,.72);
    white-space:nowrap}

/* ============================================================
   Horizontal track
   ============================================================ */
/* The section is made tall by JS (track width + one viewport). While it is
   on screen the inner sticky layer stays pinned and the track is translated
   sideways in step with the vertical scroll, so the wheel and trackpad keep
   working exactly as they normally would. */
.hscroll{position:relative}
.hscroll-sticky{position:sticky;top:0;height:100svh;overflow:hidden}
.hscroll-track{display:flex;align-items:stretch;height:100%;
    will-change:transform;backface-visibility:hidden}

/* The bottom padding has to clear the indicator and rail that sit at the foot
   of the pinned area, or panel copy runs straight into the SCROLL cue. */
.hscroll{--hfoot:clamp(96px,13vh,140px)}
.hpanel{flex:0 0 var(--vw,100vw);height:100%;position:relative;display:flex;
    padding:clamp(90px,10vh,130px) var(--pad) var(--hfoot)}
/* flex-start, not center: each panel's own content is a different height
   (About's text+paragraphs, News's heading+list, Service's heading alone),
   so centering each independently left their .sec-head underlines sitting
   at different heights panel to panel. Top-aligning keeps that line at
   the same spot everywhere; .about-visual/.news-list-col still center
   themselves within the row via their own align-self below. */
.hpanel-about,.hpanel-lead,.hpanel-news{align-items:flex-start;gap:clamp(30px,4vw,70px)}
/* About and News stay full-viewport width so only that panel is ever on
   screen at once — without centering, their content would sit flush left
   with all the leftover width dumped on the right. Lead (Service) is the
   exception: it only carries a heading and a short lead, so it takes just
   the width it needs, letting the first business card intentionally peek in
   alongside it as a "keep scrolling" cue. */
.hpanel-about,.hpanel-news{justify-content:center}
/* Kept narrow (heading only, no lead paragraph/scroll hint) so the panel
   + card grid together reliably fit within one viewport at max scroll —
   see the hLayout()/htail comment in app.js for what happens when they
   don't. */
.hpanel-lead{flex:0 0 auto;padding-right:clamp(20px,2.4vw,32px)}
.hpanel-lead .hp-body{flex:0 0 auto;width:min(220px,20vw)}
/* News's heading/tabs sit in a fixed-width left column now, with the list
   itself as a second column alongside it — same shape as About's text and
   image side by side, rather than the whole thing stacked in one block. */
.hpanel-news .hp-body.news-head{flex:0 0 auto;width:min(400px,32vw);max-width:none}
.hpanel-news .news-list-col{flex:1 1 0;min-width:0;max-width:640px;align-self:center}
.hp-body{flex:1 1 0;min-width:0;max-width:640px;align-self:flex-start}
.hpanel .sec-head{margin-bottom:clamp(20px,3vh,38px)}
.hpanel .h2{margin-bottom:clamp(18px,2.6vh,30px)}
.hpanel .about-txt p{font-size:13.5px;line-height:2.1}
.hpanel .about-txt .mbtn{margin-top:clamp(20px,3vh,34px)}
.hpanel .sec-lead{margin-bottom:0}
.hpanel-about .about-visual{flex:0 0 min(42vw,560px);height:min(60vh,520px);
    margin-top:0;align-self:flex-start}

/* "keep going" cue at the end of the service intro */
.hp-hint{display:flex;align-items:center;gap:12px;margin-top:clamp(26px,4vh,44px);
    font-size:10px;letter-spacing:.22em;color:var(--fg-dim)}
.hp-hint span{width:46px;height:1px;background:var(--line-strong);position:relative;overflow:hidden}
.hp-hint span::after{content:"";position:absolute;inset:0;background:var(--fg);
    animation:hsweep 2s infinite var(--ease)}
@keyframes hsweep{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}

/* One business per card */
.hcard{flex:0 0 clamp(300px,27vw,420px);align-self:center;
    height:min(64vh,580px);margin-right:clamp(18px,2vw,32px);
    border:1px solid var(--line);border-radius:22px;overflow:hidden;
    padding:clamp(24px,2.4vw,36px);display:flex;flex-direction:column;
    /* z-index (not just position:relative) so this establishes its own
       stacking context — otherwise .hcard-photo's z-index:-1 escapes past
       this element's own background to whatever real stacking context
       contains it, ending up hidden behind unrelated page content instead
       of just behind this card's text. */
    position:relative;z-index:0;background:var(--bg)}
.hcard:first-of-type{margin-left:clamp(8px,2vw,40px)}
/* Service's 5 cards sit in a 2-row brick grid — row 1 holds cards 1/3/5,
   row 2 holds 2/4 inset by half a card so it nests into the gaps between
   row 1's cards, same layout as the reference. This whole grid is one
   flex item inside #htrack (see index.html), so it still scrolls sideways
   together with Hero/About/News as a single horizontal journey — only the
   5 cards themselves are arranged with CSS grid instead of also being
   individual items in that outer flex row. */
.svc-grid{flex:0 0 auto;align-self:center;
    display:grid;grid-template-columns:repeat(6,clamp(100px,9vw,155px));
    /* vh, not vw — a wide-but-short window still only has so much vertical
       room for 2 rows before the top one runs under the fixed header;
       sizing this off width alone (like the columns above) ignored that. */
    grid-auto-rows:clamp(190px,24vh,340px);
    column-gap:clamp(18px,2vw,28px);row-gap:clamp(18px,2vw,28px);
    margin-right:clamp(18px,2vw,32px)}
.svc-grid .hcard:nth-child(1){grid-column:1/span 2;grid-row:1}
.svc-grid .hcard:nth-child(2){grid-column:2/span 2;grid-row:2}
.svc-grid .hcard:nth-child(3){grid-column:3/span 2;grid-row:1}
.svc-grid .hcard:nth-child(4){grid-column:4/span 2;grid-row:2}
.svc-grid .hcard:nth-child(5){grid-column:5/span 2;grid-row:1}
/* A perfect circle rather than the landscape rectangle — a circle has far
   less usable area near its own top/bottom than a rectangle of the same
   footprint, so the catch line, body copy and tag chips are dropped from
   this compact view entirely rather than just shrunk (they're still on
   the linked service page). What's left — number and title — centers in
   the middle, where the circle is actually wide enough for text. Grid
   items also ignore .hcard's own flex/align-self (those only apply inside
   a flex container) — clearing them here too so nothing lingers oddly if
   this selector's specificity ever changes. */
.svc-grid .hcard{flex:none;align-self:auto;margin-right:0;margin-left:0;
    aspect-ratio:1/1;height:auto;border-radius:50%;
    align-items:center;justify-content:center;text-align:center;
    padding:clamp(14px,1.6vw,22px)}
.svc-grid .hcard .n{position:absolute;top:clamp(18px,2vw,26px);left:0;right:0;text-align:center}
.svc-grid .hcard .ttl{margin:0;padding:0;border-bottom:0}
.svc-grid .hcard .ttl .e{min-height:0;font-size:clamp(15px,1.3vw,19px)}
.svc-grid .hcard .catch,.svc-grid .hcard p,.svc-grid .hcard .chips{display:none}
.svc-grid .hcard .ar{top:auto;bottom:clamp(14px,1.6vw,20px);right:0;left:0;margin-inline:auto;
    width:26px;height:26px}
.htail{flex:0 0 clamp(40px,7vw,120px)}
/* A faint photo fades in behind the card's own text on hover, instead of a
   flat background-color swap. Stays low-opacity throughout — at full
   strength it would fight with the text sitting on top of it. */
.hcard-photo{position:absolute;inset:0;z-index:-1;
    background-size:cover;background-position:center;
    opacity:0;transform:scale(1.04);
    transition:opacity .6s var(--ease),transform .6s var(--ease)}
.hcard:hover .hcard-photo{opacity:.26;transform:scale(1)}
.hcard .n{display:block;font-size:clamp(19px,1.7vw,26px);font-weight:600;
    line-height:1.2;letter-spacing:-.01em;color:var(--fg)}
.hcard .ttl{display:block;margin:clamp(14px,2vh,22px) 0 clamp(14px,2vh,20px);
    padding-bottom:clamp(12px,1.6vh,18px);border-bottom:1px solid var(--line)}
/* "Information & Communication" wraps to two lines while every other title
   sits on one — reserve two lines' worth of height across the board so the
   card bodies below don't all shift to match whichever title is longest. */
.hcard .ttl .e{display:block;font-size:clamp(19px,1.7vw,26px);font-weight:600;
    line-height:1.2;letter-spacing:-.01em;min-height:2.4em}
.hcard .ttl .j{display:block;font-size:11.5px;color:var(--fg-dim);letter-spacing:.16em;margin-top:8px}
.hcard .catch{font-size:13.5px;font-weight:500;line-height:1.9;margin-bottom:10px}
.hcard p{font-size:12.5px;line-height:2;color:var(--fg-dim);letter-spacing:.04em}
.hcard .chips{margin-top:auto;padding-top:clamp(16px,2.4vh,26px)}
.hcard .ar{position:absolute;top:clamp(20px,2.2vw,30px);right:clamp(20px,2.2vw,30px);
    width:36px;height:36px;border:1px solid var(--line);border-radius:50%;
    display:grid;place-content:center;overflow:hidden;
    transition:background .5s var(--ease),color .5s var(--ease),border-color .5s var(--ease)}
.hcard .ar span{display:block;transition:transform .5s var(--ease)}
.hcard:hover .ar{background:var(--accent);color:var(--on-accent);border-color:transparent}
.hcard:hover .ar span{transform:translate(3px,-3px)}

/* Blog preview cards reuse the .hcard shell (incl. the photo hover) but
   skip the chips list, so they read fine at a shorter height. News uses
   the plain row-list (.news/.tabs below) instead — the two used to be the
   other way around. */
.hcard-news{height:min(40vh,320px)}
.hcard-news .n{display:block;font-size:13px;font-weight:500;letter-spacing:.08em;color:var(--fg-dim)}
.hcard-news .ttl{margin:10px 0 14px;padding-bottom:0;border-bottom:0}
.hcard-news .ttl .j{margin-top:0;font-size:11.5px}
.hcard-news .catch{font-size:15px;font-weight:600;line-height:1.7;margin-bottom:0;color:var(--fg)}
/* The trailing "view all" card — centered label instead of the usual
   top-left number / bottom-right arrow layout. */
.hcard-more{flex:0 0 clamp(180px,14vw,240px);height:min(40vh,320px);
    align-items:center;justify-content:center;text-align:center}
.hcard-more .more-lbl{font-size:15px;font-weight:600;letter-spacing:.14em;line-height:1.6}
.hcard-more .ar{position:static;margin:16px auto 0}

/* Blog's own horizontal scroller — plain native overflow, independent of
   the pinned Hero/About/News/Service track above. Left inset comes from the
   scroller's own padding (matching .wrap elsewhere) rather than the track's
   usual small first-card margin, which isn't enough space on its own and
   left the first card looking flush against the edge. */
/* mandatory (not proximity) so it always comes to rest on a full card
   rather than resting mid-card at the viewport edge — app.js's wheel
   handler eases scrollLeft toward a target rather than jumping it, and
   snap only resolves once that settles. scroll-padding-left has to match
   the container's own padding-left: without it, the snap algorithm ignores
   the padding and treats the first card as unsnappable at rest, so the
   browser silently scrolled ~60px to the *next* snap point on first paint —
   the whole row starting pre-shifted, first card clipped, on every load. */
/* Scrollbar hidden — as a native element it always runs edge-to-edge and
   can't be inset to line up with the card row's own left padding, so its
   left end never matched the cards' visual start. The prev/next buttons
   are the discoverable affordance now; the scrollbar was redundant anyway. */
/* .blog-scroller lives outside .wrap so cards can bleed edge to edge, but
   that means its left inset can't just be var(--pad) — .wrap is also
   centered by max-width, so past that breakpoint its content sits further
   in than var(--pad) alone. Matching that centering keeps the first card
   flush under the heading above it. */
.blog-scroller{display:flex;overflow-x:auto;padding:4px var(--pad) 20px;
    padding-left:max(var(--pad),calc((100% - var(--maxw)) / 2 + var(--pad)));
    scrollbar-width:none;
    scroll-snap-type:x mandatory;
    scroll-padding-left:max(var(--pad),calc((100% - var(--maxw)) / 2 + var(--pad)))}
.blog-scroller::-webkit-scrollbar{display:none}
.blog-scroller .hcard:first-of-type{margin-left:0}
.blog-scroller .hcard{scroll-snap-align:start}
/* Whichever edge still has more cards past it fades to transparent instead
   of hard-clipping the next card mid-way — reads as "more this way" rather
   than looking cut off. app.js toggles these on load/scroll/resize based on
   how close to each end the scroller actually is. */
.blog-scroller.fade-r{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 48px),transparent 100%);
    mask-image:linear-gradient(to right,#000 calc(100% - 48px),transparent 100%)}
.blog-scroller.fade-l{-webkit-mask-image:linear-gradient(to right,transparent 0,#000 48px);
    mask-image:linear-gradient(to right,transparent 0,#000 48px)}
.blog-scroller.fade-l.fade-r{-webkit-mask-image:linear-gradient(to right,transparent 0,#000 48px,#000 calc(100% - 48px),transparent 100%);
    mask-image:linear-gradient(to right,transparent 0,#000 48px,#000 calc(100% - 48px),transparent 100%)}

/* Prev/next — a scrollbar alone doesn't read as "there's more to see", so
   these sit next to the category tabs as a quieter, more obvious handle on
   the same eased scroll. Same icon-button look as .hcard .ar, just always
   visible instead of a hover reveal. */
.blog-controls{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.blog-nav{display:flex;gap:8px;flex:0 0 auto}
.blog-nav-btn{width:36px;height:36px;border:1px solid var(--line);border-radius:var(--r-icon);
    display:grid;place-content:center;color:var(--fg-dim);
    transition:background .35s var(--ease),color .35s var(--ease),border-color .35s var(--ease),opacity .35s var(--ease)}
.blog-nav-btn:hover{background:var(--accent);color:var(--on-accent);border-color:transparent}
.blog-nav-btn:disabled{opacity:.3;pointer-events:none}
/* Two copies of the same buttons exist (see index.html) — only one is ever
   in the layout at a time, toggled by breakpoint below. */
.blog-nav-mobile{display:none}

/* Fixed to one spot in the viewport for good — no repositioning based on
   state, so it never appears to drift. Each button's glyph (down / up,
   baked into its own SVG) flips to horizontal only while the pinned rail
   still has sideways travel left — not to track which way you're actually
   scrolling, which is what used to flip it confusingly at the bottom of the
   page and, on the way back through the rail, left the two buttons'
   arrowheads pointing straight at each other. It's a single phase switch,
   not a direction one: sideways vs. vertical, never back and forth.
   Bordered rather than solid-filled — same treatment as .blog-nav-btn, so
   the pair reads as one considered control instead of a lone filled bubble
   with a second one bolted on beside it. */
.scroll-dir{all:unset;box-sizing:border-box;position:fixed;right:var(--pad);
    bottom:clamp(18px,3vh,32px);z-index:50;width:40px;height:40px;
    border-radius:50%;border:1px solid var(--line);background:var(--card);cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    transition:background .3s var(--ease),border-color .3s var(--ease),opacity .3s var(--ease)}
.scroll-dir:hover{background:var(--fg);border-color:transparent}
.scroll-dir:hover svg{color:var(--on-accent)}
.scroll-dir svg{display:block;color:var(--fg-dim);transition:transform .4s var(--ease)}
/* Same -90° turn on both buttons: main's ↓ becomes →, back's ↑ becomes ←.
   Back sits to the left of main on screen, so this pairing keeps them
   facing away from each other (← →) in the sideways phase too, not the
   converging ▶◀ that a mismatched rotation would produce. */
.scroll-dir.dir-h svg{transform:rotate(-90deg)}
/* Nowhere further to go once the footer's in view. */
.scroll-dir.at-end{opacity:0;pointer-events:none}

/* Sits just left of the main button — app.js shows it any time scrollY > 0
   (nothing to go back to from the very top). */
.scroll-dir-back{right:calc(var(--pad) + 48px);opacity:0;pointer-events:none}
.scroll-dir-back.show{opacity:1;pointer-events:auto}

/* ============================================================
   Section shell
   ============================================================ */
section{position:relative}
.sec{padding:clamp(90px,13vw,190px) 0}
.sec-head{display:flex;align-items:center;gap:14px;border-bottom:1px solid var(--line);
    padding-bottom:12px;margin-bottom:clamp(34px,5vw,64px)}
.sec-head .sq{width:6px;height:6px;background:var(--accent)}
.sec-head .lbl{font-size:11px;letter-spacing:.24em;text-transform:uppercase;font-weight:600}
.sec-head .no{margin-left:auto;font-size:10px;color:var(--fg-dim);letter-spacing:.16em}
.h2{font-size:clamp(24px,3.8vw,52px);font-weight:600;line-height:1.15;letter-spacing:-.01em}
/* Secondary/supplementary section heading (e.g. "その他のお知らせ" below an
   article) — same weight and treatment as .h2, just a notch down so it
   doesn't compete with the actual page heading above it. */
.h2.sm{font-size:clamp(18px,2.6vw,28px)}

/* reveal */
.rv{opacity:0;transform:translateY(38px);
    transition:opacity .95s var(--ease),transform .95s var(--ease)}
.rv.in{opacity:1;transform:none}
.rv[data-d="1"]{transition-delay:.09s}
.rv[data-d="2"]{transition-delay:.18s}
.rv[data-d="3"]{transition-delay:.27s}
.rv[data-d="4"]{transition-delay:.36s}

/* marquee button */
.mbtn{display:inline-flex;align-items:center;gap:16px;border:1px solid var(--line-strong);
    border-radius:var(--r-btn);height:62px;padding-inline:34px;overflow:hidden;position:relative;isolation:isolate;
    font-size:12px;letter-spacing:.16em}
.mbtn::before{content:"";position:absolute;inset:0;background:var(--fg);z-index:-1;
    transform:translateY(101%);transition:transform .55s var(--ease)}
.mbtn:hover::before{transform:translateY(0)}
.mbtn:hover{color:var(--bg);border-color:transparent}
/* A square badge can't spin like the old circle did — it reads as a diamond.
   Nudge the arrow along its own axis instead. */
.mbtn .ar{width:26px;height:26px;border-radius:var(--r-icon);border:1px solid currentColor;
    display:grid;place-content:center;font-size:11px;overflow:hidden}
.mbtn .ar span{display:block;transition:transform .5s var(--ease)}
.mbtn:hover .ar span{transform:translate(3px,-3px)}

/* ============================================================
   About
   ============================================================ */
.about-grid{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(30px,5vw,80px);align-items:end}
.about-grid .h2{max-width:14ch}
.about-txt p{font-size:14px;line-height:2.3;color:var(--fg-dim);letter-spacing:.05em}
.about-txt p+p{margin-top:1.6em}
.about-txt .mbtn{margin-top:40px}
.about-visual{margin-top:clamp(40px,6vw,90px);height:clamp(220px,38vw,520px);border-radius:6px;
    position:relative;overflow:hidden;background:var(--card)}
.about-visual::after{content:"";position:absolute;inset:0;
  background:conic-gradient(from 210deg at 40% 50%,#d6d5d0,#c9c8c2,color-mix(in srgb,var(--accent) 22%,#ddd),#e2e1dc,#d6d5d0);
  filter:blur(4px);transform:scale(1.2);animation:spinbg 24s linear infinite}
@keyframes spinbg{to{transform:scale(1.2) rotate(360deg)}}
.about-visual .cap{position:absolute;left:24px;bottom:20px;z-index:2;font-size:11px;
    letter-spacing:.22em;color:#fff;mix-blend-mode:difference}
.about-visual img{position:absolute;inset:0;z-index:1;width:100%;height:100%;object-fit:cover;filter:saturate(.35)}

.center{display:flex;justify-content:center;margin-top:clamp(44px,6vw,84px)}

/* ============================================================
   Service
   ============================================================ */
.svc{border-top:1px solid var(--line)}
.svc-item{border-bottom:1px solid var(--line);display:grid;
    grid-template-columns:88px minmax(220px,1fr) 1.5fr auto;gap:clamp(16px,3vw,48px);
    align-items:start;padding:clamp(26px,3.4vw,52px) 0;position:relative;transition:padding .5s var(--ease)}
.svc-item::before{content:"";position:absolute;left:0;right:0;top:0;bottom:0;background:var(--card);
    opacity:0;transition:opacity .5s var(--ease);z-index:-1;border-radius:4px}
.svc-item:hover::before{opacity:.55}
.svc-item:hover{padding-inline:18px}
.svc-item .n{font-size:11px;color:var(--fg-dim);letter-spacing:.14em;padding-top:8px}
.svc-item .ttl .e{display:block;font-size:clamp(19px,2.5vw,34px);font-weight:600;line-height:1.2;letter-spacing:-.01em}
.svc-item .ttl .j{display:block;font-size:12px;color:var(--fg-dim);letter-spacing:.16em;margin-top:8px}
.svc-item p{font-size:13px;line-height:2.15;color:var(--fg-dim);letter-spacing:.04em}
.svc-item .catch{color:var(--fg);font-size:14px;font-weight:500;line-height:1.9;margin-bottom:10px}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px}
.chips li{font-size:10.5px;letter-spacing:.06em;color:var(--fg-dim);
    border:1px solid var(--line);border-radius:99px;padding:3px 11px}
.sec-lead{font-size:13.5px;line-height:2.1;color:var(--fg-dim);max-width:60ch;
    margin-bottom:clamp(34px,5vw,64px)}
.svc-item .ar{width:40px;height:40px;border:1px solid var(--line);border-radius:var(--r-icon);
    display:grid;place-content:center;flex:none;overflow:hidden;
    transition:background .5s var(--ease),color .5s var(--ease),border-color .5s var(--ease)}
.svc-item .ar span{display:block;transition:transform .5s var(--ease)}
.svc-item:hover .ar{background:var(--accent);color:var(--on-accent);border-color:transparent}
.svc-item:hover .ar span{transform:translate(3px,-3px)}

/* ============================================================
   Strengths
   ============================================================ */
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,3vw,40px);
    margin-bottom:clamp(56px,8vw,120px)}
.stat{border-top:1px solid var(--line-strong);padding-top:20px}
.stat .val{display:flex;align-items:flex-end;font-size:clamp(48px,9vw,132px);font-weight:600;
    line-height:.9;letter-spacing:-.03em}
.stat .unit{font-size:clamp(12px,1.1vw,15px);margin-left:.5em;color:var(--accent-ink);
    letter-spacing:.12em;line-height:2.4;white-space:nowrap}
.stat .sep{display:inline-block}
.digit{display:inline-block;height:1em;overflow:hidden;position:relative;width:.62em}
.digit .col{display:block;transition:transform 1.5s var(--ease)}
.digit .col b{display:block;height:1em;line-height:1;font-weight:600}
.stat .cap{margin-top:16px;font-size:12px;letter-spacing:.18em;color:var(--fg-dim)}

/* Left column is a sticky field of dots standing in for the 5 items on the
   right; the dot matching whichever item is centered in the viewport grows
   and darkens (see the IntersectionObserver in app.js). Positions are
   scattered by hand (not a grid) for an organic, non-mechanical feel. */
.str-wrap{display:grid;grid-template-columns:minmax(140px,220px) 1fr;gap:clamp(24px,4vw,64px);align-items:start}
.str-motif{position:sticky;top:114px;height:clamp(280px,32vw,380px)}
.str-dot{position:absolute;width:14px;height:14px;border-radius:50%;background:var(--line-strong);
    transform:translate(-50%,-50%) scale(1);transition:transform .6s var(--ease),background .6s var(--ease)}
.str-dot.on{background:var(--accent);transform:translate(-50%,-50%) scale(2.6)}

.str{display:flex;flex-direction:column}
.str li{padding:clamp(28px,4vw,56px) 0;border-top:1px solid var(--line);transition:opacity .5s var(--ease);opacity:.4}
.str li:last-child{border-bottom:1px solid var(--line)}
.str li.on{opacity:1}
.str .n{font-size:11px;color:var(--accent-ink);letter-spacing:.16em}
.str h3{font-size:clamp(16px,1.8vw,24px);font-weight:500;line-height:1.6;margin:14px 0 16px}
.str p{font-size:13px;line-height:2.15;color:var(--fg-dim);letter-spacing:.04em;max-width:56ch}

/* ============================================================
   Flow
   ============================================================ */
.flow{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--line)}
.flow li{background:var(--bg);padding:clamp(20px,2.2vw,34px);position:relative}
.flow .n{font-family:"futura-pt";font-size:clamp(34px,4vw,58px);font-weight:600;line-height:1;
    color:var(--line-strong);display:inline-block;transform-origin:left center;
    transition:transform .4s var(--ease)}
.flow li:hover .n{transform:scale(1.2)}
.flow h3{font-size:15px;font-weight:500;margin:18px 0 12px}
.flow p{font-size:12px;line-height:2;color:var(--fg-dim)}

/* ============================================================
   News
   ============================================================ */
.tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:34px}
.tabs button{border:1px solid var(--line);border-radius:var(--r-btn);padding:8px 20px;font-size:11px;
    letter-spacing:.14em;color:var(--fg-dim);transition:.4s var(--ease)}
.tabs button.on{background:var(--fg);color:var(--bg);border-color:transparent}
.news li{border-top:1px solid var(--line)}
.news li:last-child{border-bottom:1px solid var(--line)}
/* transform, not padding-left — padding on a grid item forces a layout
   recalc every animation frame (grid tracks depend on it), which read as
   stutter; translate is compositor-only. */
.news a{display:grid;grid-template-columns:110px 120px 1fr auto;gap:clamp(12px,2.4vw,36px);
    align-items:center;padding:clamp(18px,2.2vw,30px) 0;transition:transform .5s var(--ease)}
.news a:hover{transform:translateX(16px)}
.news time{font-size:12px;color:var(--fg-dim);letter-spacing:.1em}
.news .cat{font-size:10px;letter-spacing:.14em;border:1px solid var(--line);border-radius:99px;
    padding:4px 0;text-align:center;color:var(--fg-dim)}
.news .ttl{font-size:14px;line-height:1.7}
.news .ar{opacity:.3;transition:.45s var(--ease)}
.news a:hover .ar{opacity:1;transform:translateX(6px)}
.news li.hide{display:none}
/* Same filtering behavior, but for Blog's cards — .hcard's own
   display:flex otherwise wins the cascade against a bare .hide. */
.hcard.hide{display:none}

/* ============================================================
   Company profile
   ============================================================ */
.profile{border-top:1px solid var(--line)}
.profile>div{display:grid;grid-template-columns:minmax(160px,220px) 1fr;
    gap:clamp(14px,3vw,48px);border-bottom:1px solid var(--line);
    padding:clamp(16px,2vw,26px) 0}
.profile dt{font-size:11.5px;letter-spacing:.16em;color:var(--fg-dim);padding-top:3px}
.profile dd{font-size:13.5px;line-height:2}
.profile dd .sub{display:block;margin-top:4px;font-size:11.5px;letter-spacing:.1em;color:var(--fg-dim)}

/* ============================================================
   Sub page — hero / breadcrumb
   ============================================================ */
.page-hero{position:relative;overflow:hidden;padding:clamp(110px,10vw,150px) 0 clamp(32px,4vw,56px);
    border-bottom:1px solid var(--line)}
.page-hero .wrap{position:relative;z-index:2}
.crumb{display:flex;align-items:center;gap:10px;font-size:10.5px;letter-spacing:.16em;
    color:var(--fg-dim);text-transform:uppercase;margin-bottom:clamp(18px,2.6vw,32px)}
.crumb a{transition:color .35s var(--ease)}
.crumb a:hover{color:var(--accent-ink)}
.crumb [aria-current]{color:var(--fg)}
.page-ttl{font-size:clamp(34px,7vw,96px);line-height:.95;font-weight:600;letter-spacing:-.025em}
.page-ttl .ln{display:block;overflow:hidden;padding-bottom:.22em;margin-bottom:-.22em}
.page-ttl .ln>span{display:block;transform:translateY(105%)}
/* Held here — not auto-playing — until app.js adds .ttl-ready once the
   futura-pt font is settled one way or the other, so the entrance never
   starts in the fallback font and pops to the real one partway through. */
.page-ttl.ttl-ready .ln>span{animation:rise 1.05s var(--ease) forwards}
@keyframes rise{to{transform:translateY(0)}}
.page-sub{margin-top:14px;font-size:12px;letter-spacing:.3em;color:var(--fg-dim)}
.ul{border-bottom:1px solid var(--line-strong);padding-bottom:2px;transition:color .35s var(--ease)}
.ul:hover{color:var(--accent-ink)}

/* ============================================================
   Service detail pages
   ============================================================ */
.ov{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,5vw,70px);align-items:start}
.ov p{font-size:13.5px;line-height:2.15;color:var(--fg-dim)}
.ov p+p{margin-top:1.3em}
.ov .catch,.about-txt p.catch,.hpanel .about-txt p.catch{font-size:clamp(17px,1.8vw,22px);font-weight:500;line-height:1.85;
    color:var(--fg);margin:clamp(18px,2.6vw,28px) 0 16px}
.about-txt p.catch+p{margin-top:0}
.ov .about-visual{margin-top:0}

/* A copy of .str's look, kept separate so item count doesn't matter — .str
   always spans its last child full-width, which assumes an odd total (true
   on the homepage, not here). Add .full by hand on a card when a page's own
   count is odd and the last row should stretch. */
.lineup{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line)}
.lineup li{background:var(--bg);padding:clamp(24px,3vw,44px);transition:background .5s var(--ease)}
.lineup li:hover{background:var(--card)}
.lineup .n{font-size:11px;color:var(--accent-ink);letter-spacing:.16em}
.lineup h3{font-size:clamp(16px,1.8vw,24px);font-weight:500;line-height:1.6;margin:14px 0 16px}
.lineup p{font-size:13px;line-height:2.15;color:var(--fg-dim);letter-spacing:.04em}
.lineup li.full{grid-column:1/-1}
.lineup.cols-3{grid-template-columns:repeat(3,1fr)}

/* About page's approach list: same type scale as .lineup, but a plain
   vertical stack — no card grid, no number badge, no hover color swap. */
.approach-list{display:flex;flex-direction:column}
.approach-list li{padding:clamp(28px,4vw,56px) 0;border-top:1px solid var(--line)}
.approach-list li:last-child{border-bottom:1px solid var(--line)}
.approach-list h3{font-size:clamp(16px,1.8vw,24px);font-weight:500;line-height:1.6;margin-bottom:16px}
.approach-list p{font-size:13px;line-height:2.15;color:var(--fg-dim);letter-spacing:.04em;max-width:64ch}

.cat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line)}
.cat-grid li{background:var(--bg);padding:clamp(20px,2.4vw,30px) clamp(10px,1.6vw,20px);
    text-align:center;font-size:13px;letter-spacing:.08em}

/* Cross-links to the other five businesses, at the foot of every service
   page — the six pages read as one connected set rather than dead ends. */
.svc-nav{border-top:1px solid var(--line)}
.svc-nav a{display:flex;align-items:center;gap:20px;padding:clamp(18px,2.4vw,28px) 0;
    border-bottom:1px solid var(--line);transition:padding-left .5s var(--ease)}
.svc-nav a:hover{padding-left:14px}
.svc-nav .n{font-size:11px;color:var(--fg-dim);letter-spacing:.14em;min-width:34px}
.svc-nav .ttl{flex:1;display:flex;flex-wrap:wrap;align-items:baseline;gap:12px}
.svc-nav .e{font-size:clamp(16px,1.6vw,22px);font-weight:600}
.svc-nav .j{font-size:11px;color:var(--fg-dim);letter-spacing:.14em}
.svc-nav .ar{opacity:.4;transition:.4s var(--ease);font-size:16px}
.svc-nav a:hover .ar{opacity:1;transform:translateX(4px)}

/* ============================================================
   Contact form
   ============================================================ */
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,2.6vw,32px) clamp(24px,3vw,40px)}
.field{display:flex;flex-direction:column;gap:10px}
.field.full{grid-column:1/-1}
.field label{font-size:12px;letter-spacing:.1em;color:var(--fg-dim)}
.field label .req{color:var(--accent-ink);margin-left:.5em;font-size:10px;letter-spacing:.04em}
.field input,.field select,.field textarea{
  width:100%;font:inherit;font-size:14px;color:var(--fg);background:transparent;
  border:1px solid var(--line);border-radius:var(--r-btn);padding:14px 16px;
  transition:border-color .35s var(--ease)}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--line-strong)}
.field textarea{resize:vertical;min-height:170px;line-height:1.8}
.field.select-wrap{position:relative}
.field.select-wrap select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:36px}
.field.select-wrap::after{content:"▾";position:absolute;right:16px;bottom:15px;
    font-size:11px;color:var(--fg-dim);pointer-events:none}

.check{grid-column:1/-1;display:flex;align-items:flex-start;gap:12px;
    font-size:12.5px;line-height:1.9;color:var(--fg-dim);margin-top:clamp(10px,1.6vw,18px)}
.check input{margin-top:5px;width:16px;height:16px;accent-color:var(--fg);flex:none}

.form-submit{grid-column:1/-1;display:flex;justify-content:flex-start;
    margin-top:clamp(14px,2vw,22px)}
.form-submit .mbtn{border:1px solid var(--fg);cursor:pointer}

/* ============================================================
   Product cards with a catalog (image-forward, 3 across)
   ============================================================ */
/* Products that have a catalog get a full card: cover on top, sized to
   actually read as a cover, with the product's own copy underneath. A
   product with no catalog (network build/maintenance) doesn't fit this
   card — it runs as a plain full-width row underneath instead. */
.prod-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,2.6vw,32px);
    margin-bottom:clamp(20px,2.6vw,32px)}
.prod-card{display:block;border-radius:8px;overflow:hidden;
    background:var(--bg);transition:background .5s var(--ease),transform .5s var(--ease),box-shadow .5s var(--ease)}
.prod-card:hover{background:var(--card);transform:translateY(-6px);box-shadow:0 24px 44px -24px rgba(0,0,0,.35)}
.prod-cover{position:relative;aspect-ratio:3/4;overflow:hidden;background:var(--card)}
.prod-cover img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
.prod-cover::after{content:"WEBで見る ↗";position:absolute;inset:auto 0 0 0;padding:11px 14px;
    font-size:11px;letter-spacing:.08em;text-align:center;color:var(--on-accent);background:var(--accent);
    transform:translateY(100%);transition:transform .4s var(--ease)}
.prod-card:hover .prod-cover::after{transform:translateY(0)}
.prod-body{padding:clamp(18px,2.2vw,26px)}
.prod-body .n{font-size:11px;color:var(--fg-dim);letter-spacing:.14em}
.prod-body h3{font-size:clamp(15px,1.4vw,18px);font-weight:600;line-height:1.5;margin:10px 0}
.prod-body p{font-size:12px;color:var(--fg-dim);line-height:1.9}
.prod-link{display:block;margin-top:14px;font-size:11px;letter-spacing:.08em;color:var(--fg-dim);
    transition:color .35s var(--ease)}
.prod-card:hover .prod-link{color:var(--fg)}

.prod-plain{border:1px solid var(--line);border-radius:8px;padding:clamp(24px,3vw,36px)}
.prod-plain .n{font-size:11px;color:var(--fg-dim);letter-spacing:.14em}
.prod-plain h3{font-size:clamp(16px,1.6vw,20px);font-weight:600;line-height:1.5;margin:12px 0 14px}
.prod-plain p{font-size:13px;color:var(--fg-dim);line-height:2.1;max-width:70ch}

/* ============================================================
   Flipbook viewer (catalog)
   ============================================================ */
.flipbook{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;padding:clamp(16px,4vw,48px);background:rgba(10,10,10,.92)}
.flipbook.open{display:flex}
.flipbook-inner{position:relative;width:100%;max-width:920px;height:100%;max-height:88vh;display:flex;flex-direction:column;align-items:center}
/* Pages stack in normal flow and the stage scrolls vertically — the nav
   buttons live outside it (siblings, absolutely positioned over it) so
   they stay put on screen instead of scrolling away with the pages. */
.flipbook-stage{position:relative;width:100%;flex:1;overflow:auto;min-height:0;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}
.flipbook-stage img{display:block;width:calc(min(100%,720px) * var(--zoom,1));max-width:none;height:auto;margin:0 auto clamp(16px,2.4vw,28px);box-shadow:0 20px 60px rgba(0,0,0,.5)}
.flipbook-stage img:last-child{margin-bottom:0}
.flipbook-nav{position:absolute;top:50%;transform:translateY(-50%);width:48px;height:48px;border-radius:50%;border:1px solid rgba(255,255,255,.3);background:rgba(255,255,255,.06);color:#fff;font-size:18px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s,border-color .2s;z-index:5}
.flipbook-nav:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.6)}
.flipbook-nav:disabled{opacity:.25;cursor:default;pointer-events:none}
.flipbook-nav.prev{left:clamp(-8px,-2vw,8px)}
.flipbook-nav.next{right:clamp(-8px,-2vw,8px)}
.flipbook-close{position:absolute;top:-4px;right:-4px;width:40px;height:40px;border-radius:50%;border:1px solid rgba(255,255,255,.3);background:rgba(255,255,255,.06);color:#fff;font-size:16px;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:5}
.flipbook-close:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.6)}
/* Right padding reserves room for the close button, which sits fixed at
   the inner box's top-right corner — without it, the count/zoom cluster
   (also right-aligned) runs underneath it. */
.flipbook-head{width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;color:#fff;padding:0 clamp(48px,6vw,64px) clamp(10px,1.4vw,16px) 0;flex-shrink:0}
.flipbook-title{font-size:13px;letter-spacing:.04em}
.flipbook-tools{display:flex;align-items:center;gap:clamp(14px,2vw,22px)}
.flipbook-zoom{display:flex;align-items:center;gap:8px}
.flipbook-zoom-btn{width:22px;height:22px;border-radius:50%;border:1px solid rgba(255,255,255,.3);background:rgba(255,255,255,.06);color:#fff;font-size:13px;line-height:1;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s,border-color .2s}
.flipbook-zoom-btn:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.6)}
.flipbook-zoom-btn:disabled{opacity:.25;cursor:default;pointer-events:none}
.flipbook-zoom-val{font-family:futura-pt,sans-serif;font-size:12px;letter-spacing:.04em;color:rgba(255,255,255,.7);min-width:36px;text-align:center}
.flipbook-count{font-family:futura-pt,sans-serif;font-size:12px;letter-spacing:.08em;color:rgba(255,255,255,.6)}
@media (max-width:760px){
  .flipbook-nav{width:38px;height:38px;font-size:15px}
  .flipbook-nav.prev{left:0}
  .flipbook-nav.next{right:0}
  .flipbook-close{top:0;right:0}
  .flipbook-head{padding-right:44px}
  .flipbook-tools{gap:12px}
}

/* ============================================================
   News / Blog article — mirrors the CMS's public post renderer
   (post/post-head/post-meta/post-ttl/post-body/post-back), so this mock
   reads the same as what the real published/preview page will produce.
   Blog posts add a 16:9 .post-cover above the head; News omits it.
   ============================================================ */
/* #article overrides .sec's own generous clamp(90px,13vw,190px) — that
   default is sized for a full landing section, not a page that's mostly
   this one column of text sitting right under the (already short)
   page-hero; left alone it pushed the actual body below the fold on
   most screens. */
#article{padding:clamp(32px,4vw,56px) 0}
.post-cover{border-radius:8px;overflow:hidden;aspect-ratio:16/9;margin-bottom:clamp(20px,2.6vw,32px)}
.post-cover img{width:100%;height:100%;object-fit:cover;display:block}
.post-head{border-bottom:1px solid var(--line);padding-bottom:clamp(14px,1.8vw,22px);
    margin-bottom:clamp(18px,2.4vw,28px)}
.post-meta{display:flex;align-items:center;gap:14px;margin-bottom:14px}
.post-meta .cat{font-size:10px;letter-spacing:.14em;border:1px solid var(--line);
    border-radius:99px;padding:4px 14px;color:var(--fg-dim)}
.post-meta time{font-size:12px;letter-spacing:.08em;color:var(--fg-dim)}
.post-ttl{font-size:clamp(26px,3.4vw,42px);font-weight:600;line-height:1.35;letter-spacing:-.01em}
.post-note{font-size:11.5px;line-height:1.8;color:var(--fg-dim);background:var(--card);
    border-radius:var(--r-btn);padding:10px 16px;margin-bottom:clamp(18px,2.4vw,28px)}

/* Body content comes from the CMS's rich-text editor (Tiptap), sanitized to
   a fixed tag set — this is that same set's typographic treatment, so a
   dummy article here previews like a real one will. */
.post-body{max-width:760px;font-size:15px;line-height:2;color:var(--fg-dim)}
.post-body>*+*{margin-top:1.3em}
.post-body h1,.post-body h2{font-size:clamp(20px,2.4vw,27px);font-weight:600;color:var(--fg);
    letter-spacing:-.01em;margin-top:1.8em}
.post-body h3{font-size:clamp(17px,1.9vw,21px);font-weight:600;color:var(--fg);margin-top:1.6em}
.post-body a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:3px}
.post-body ul,.post-body ol{padding-left:1.4em}
.post-body ul{list-style:disc}
.post-body ol{list-style:decimal}
.post-body li+li{margin-top:.4em}
.post-body blockquote{border-left:3px solid var(--line-strong);background:var(--card);
    padding:14px 20px;font-style:italic;color:var(--fg-dim)}
.post-body img{width:100%;border-radius:4px;display:block}
.post-body img[data-size="small"]{width:25%}
.post-body img[data-size="medium"]{width:50%}
.post-body img[data-size="large"]{width:100%}

.post-back{border-top:1px solid var(--line);margin-top:clamp(44px,6vw,84px);padding-top:clamp(28px,3.6vw,44px)}

/* ============================================================
   Policy document
   ============================================================ */
.policy{border-top:1px solid var(--line)}
.policy>li{padding:clamp(28px,3.6vw,44px) 0;border-bottom:1px solid var(--line)}
.policy>li>.n{font-size:11px;color:var(--fg-dim);letter-spacing:.14em}
.policy>li>h3{font-size:clamp(16px,1.6vw,20px);font-weight:600;margin:12px 0 16px;letter-spacing:-.01em}
.policy>li>p{font-size:13px;line-height:2.15;color:var(--fg-dim);max-width:78ch}
.policy>li>p+p{margin-top:1.2em}
.policy-sub{margin-top:14px;max-width:78ch}
.policy-sub li{position:relative;padding-left:1.4em;font-size:13px;line-height:2;color:var(--fg-dim)}
.policy-sub li::before{content:"—";position:absolute;left:0}

/* ============================================================
   Access
   ============================================================ */
.access{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(24px,3vw,48px)}
.ac-card{border:1px solid var(--line);border-radius:6px;overflow:hidden}
.ac-map{position:relative;aspect-ratio:16/9;
    background:
      repeating-linear-gradient(0deg,transparent 0 27px,var(--line) 27px 28px),
      repeating-linear-gradient(90deg,transparent 0 27px,var(--line) 27px 28px),
      linear-gradient(135deg,#e4e3de,#dcdbd6)}
.ac-map .pin{position:absolute;left:50%;top:50%;translate:-50% -50%;
    width:14px;height:14px;border-radius:50%;background:var(--accent)}
.ac-map .pin::after{content:"";position:absolute;inset:-10px;border-radius:50%;
    border:1px solid var(--accent);animation:ping 2.6s var(--ease) infinite}
@keyframes ping{0%{transform:scale(.6);opacity:1}100%{transform:scale(1.8);opacity:0}}
.ac-body{padding:clamp(22px,2.6vw,36px)}
.ac-body h3{display:flex;flex-wrap:wrap;align-items:baseline;gap:12px;
    padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:18px}
.ac-body h3 .e{font-size:clamp(18px,2vw,26px);font-weight:600;letter-spacing:-.01em}
.ac-body h3 .j{font-size:11px;letter-spacing:.18em;color:var(--fg-dim)}
.ac-body address{font-style:normal;font-size:13px;line-height:2;color:var(--fg-dim)}
.ac-body .tel{display:grid;grid-template-columns:auto 1fr;gap:2px 12px;margin-top:14px;
    font-size:13px;letter-spacing:.06em}
.ac-body .tel dt{color:var(--fg-dim);font-size:10px;letter-spacing:.16em;align-self:center}
.ac-body .map{display:inline-flex;align-items:center;gap:8px;margin-top:20px;font-size:11px;
    letter-spacing:.14em;border-bottom:1px solid var(--line-strong);padding-bottom:4px;
    transition:border-color .4s var(--ease),color .4s var(--ease)}
.ac-body .map:hover{color:var(--accent-ink);border-color:var(--accent-ink)}

/* ============================================================
   CTA / Footer
   ============================================================ */
.cta{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
    border-block:1px solid var(--line)}
.cta a{background:var(--bg);padding:clamp(44px,7vw,110px) clamp(24px,4vw,64px);
    display:flex;flex-direction:column;gap:14px;position:relative;overflow:hidden;isolation:isolate;
    transition:color .5s var(--ease)}
.cta a::before{content:"";position:absolute;inset:0;background:var(--accent);z-index:-1;
    transform:translateY(100%);transition:transform .65s var(--ease)}
.cta a:hover::before{transform:translateY(0)}
.cta a:hover{color:var(--on-accent)}
.cta a:hover .sub{color:var(--on-accent);opacity:.7}
.cta .e{font-size:clamp(30px,5vw,74px);font-weight:600;line-height:1;letter-spacing:-.02em}
.cta .j{font-size:12px;letter-spacing:.2em}
.cta .sub{font-size:12px;color:var(--fg-dim);margin-top:auto;padding-top:26px;transition:.5s var(--ease)}

footer{padding:clamp(56px,7vw,100px) 0 30px}
.f-top{display:grid;grid-template-columns:1.2fr 2fr;gap:clamp(30px,5vw,70px)}
.f-brand .logo{margin-bottom:30px;gap:16px}
.f-brand .logo img{height:44px}
.f-brand .logo-name{font-size:13px;letter-spacing:.12em;color:var(--fg-dim)}
.offices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(24px,3vw,44px)}
.office h4{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;font-size:11px;
    letter-spacing:.2em;text-transform:uppercase;padding-bottom:12px;
    border-bottom:1px solid var(--line);margin-bottom:16px}
.office h4 span{font-size:11px;letter-spacing:.14em;color:var(--fg-dim)}
.office address{font-style:normal;font-size:12.5px;line-height:2;color:var(--fg-dim)}
.office .tel{display:grid;grid-template-columns:auto 1fr;gap:2px 12px;margin-top:12px;
    font-size:12.5px;letter-spacing:.06em}
.office .tel dt{color:var(--fg-dim);font-size:10px;letter-spacing:.16em;align-self:center}
.office .map{display:inline-flex;align-items:center;gap:8px;margin-top:16px;font-size:11px;
    letter-spacing:.14em;border-bottom:1px solid var(--line-strong);padding-bottom:4px;
    transition:border-color .4s var(--ease),color .4s var(--ease)}
.office .map:hover{color:var(--accent-ink);border-color:var(--accent-ink)}
.f-nav{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
.f-nav h4{font-size:10px;letter-spacing:.22em;color:var(--fg-dim);margin-bottom:16px;text-transform:uppercase}
.f-nav a{display:inline-block;font-size:12.5px;padding:5px 0;color:var(--fg-dim);transition:.35s var(--ease)}
.f-nav a:hover{color:var(--fg);transform:translateX(4px)}
.f-bot{margin-top:clamp(44px,6vw,80px);border-top:1px solid var(--line);padding-top:22px;
    display:flex;flex-wrap:wrap;gap:32px;justify-content:flex-start;align-items:center;
    font-size:11px;letter-spacing:.1em;color:var(--fg-dim)}
.f-bot .lnks{display:flex;gap:22px}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width:1080px){
  .about-grid{grid-template-columns:1fr}
  /* Stack the row: number + arrow share the top line, then the title, then
     the copy — all sharing the second column. */
  .svc-item{grid-template-columns:56px 1fr;row-gap:14px}
  .svc-item .ttl,
  .svc-item .body{grid-column:2/-1}
  .svc-item .ar{grid-row:1;grid-column:2;justify-self:end}
  .flow{grid-template-columns:repeat(2,1fr)}
  .f-top{grid-template-columns:1fr}
  .f-nav{grid-template-columns:repeat(2,1fr)}
  .ov{grid-template-columns:1fr}
  .cat-grid{grid-template-columns:repeat(3,1fr)}
  .prod-grid{grid-template-columns:repeat(2,1fr)}
  .form-grid{grid-template-columns:1fr}
}
@media (max-width:760px){
  /* Horizontal scrolling is poor on touch, so the track unwinds back into a
     normal vertical stack. JS clears the inline height/transform to match. */
  .hscroll{height:auto!important}
  .hscroll-sticky{position:static;height:auto;overflow:visible}
  .hscroll-track{display:block;height:auto;transform:none!important}
  .hpanel{flex:none;width:auto;height:auto;display:block;
      padding:clamp(80px,14vh,110px) var(--pad) clamp(40px,7vh,60px)}
  .hpanel.hero{min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end}
  .hero-foot .lead{white-space:normal}   /* one line only where there is room */
  .hpanel-about .about-visual{width:auto;height:clamp(200px,46vw,320px);margin-top:32px}
  /* Desktop panels give hp-body an explicit width (e.g. News's 72vw) to
     keep it shorter than the flex row it shares with an image or the next
     panel. Stacked on mobile there's nothing beside it to share space with,
     so that width just left-aligned the whole block with dead space on the
     right — needs to be auto to fill the padded row like every other
     section does. Matches .hpanel-lead/.hpanel-news's own selector
     specificity so it actually overrides their explicit width. */
  .hp-body,.hpanel-lead .hp-body,.hpanel-news .hp-body,.hpanel-news .hp-body.news-head{max-width:none;width:auto}
  .hp-hint{display:none}
  .hcard{width:auto;height:auto;margin:0 var(--pad) 18px}
  .hcard:first-of-type{margin-top:8px}
  /* The brick grid collapses to a plain single-column stack — no row/W to
     trace once there's no width to spare for two side-by-side rows. */
  .svc-grid{display:block;margin-right:0}
  /* Back to the plain rectangular card, full content restored — a circle
     with only a number and title makes sense as one of five nodes in a
     desktop-width brick layout, not as a lone, awkwardly stacked shape at
     phone width, and there's no room to spare there for a hover-only
     "see more" the way a desktop click-through implies. */
  .svc-grid .hcard{grid-column:auto!important;grid-row:auto!important;
      flex:none;aspect-ratio:auto;height:auto;border-radius:22px;
      align-items:stretch;justify-content:flex-start;text-align:left;
      padding:clamp(24px,2.4vw,36px);margin:0 var(--pad) 18px}
  .svc-grid .hcard:first-child{margin-top:8px}
  .svc-grid .hcard .n{position:static;text-align:left}
  .svc-grid .hcard .ttl{margin:clamp(14px,2vh,22px) 0 clamp(14px,2vh,20px);
      padding-bottom:clamp(12px,1.6vh,18px);border-bottom:1px solid var(--line)}
  .svc-grid .hcard .ttl .e{min-height:0;font-size:clamp(19px,1.7vw,26px)}
  .svc-grid .hcard .catch,.svc-grid .hcard p,.svc-grid .hcard .chips{display:block}
  .svc-grid .hcard p{-webkit-line-clamp:initial}
  .svc-grid .hcard .chips{padding-top:clamp(16px,2.4vh,26px)}
  .svc-grid .hcard .ar{top:clamp(20px,2.2vw,30px);right:clamp(20px,2.2vw,30px);
      bottom:auto;left:auto;margin-inline:0;width:36px;height:36px}
  .htail{display:none}
  .hcard .chips{margin-top:22px}
  .hcard-news,.hcard-more{height:auto}
  /* The photo is a hover reveal on desktop, but touch has no hover — show it
     faintly at rest instead, same opacity the desktop hover settles on, so
     it stays behind the text rather than fighting it. */
  .hcard-photo{opacity:.26;transform:scale(1)}
  .hpanel-lead,.hpanel-news{padding-bottom:0}
  /* Blog's scroller stays horizontal (not stacked) even on mobile, so it
     needs its own card spacing instead of the stacked-track rules above —
     the left/right inset itself already comes from .blog-scroller's own
     padding at every width. */
  .blog-scroller .hcard{width:auto;height:auto;margin:0 clamp(18px,2vw,32px) 0 0}
  .blog-scroller .hcard:first-of-type{margin-top:0}
  /* On mobile the nav buttons move under the card row instead of sitting up
     by the tabs — reachable right where you stop scrolling, rather than a
     long reach back to the top. */
  .blog-nav-desktop{display:none}
  .blog-nav-mobile{display:flex;justify-content:flex-end;margin-top:20px}

  .hd{height:64px}
  .nav{padding-top:calc(64px + clamp(10px,3vh,20px))}
  .logo img{height:44px}
  .btn-contact{display:none}
  .stats{grid-template-columns:1fr;gap:26px}
  .flow,.cta,.lineup,.lineup.cols-3{grid-template-columns:1fr}
  .lineup li.full{grid-column:auto}
  .str-wrap{grid-template-columns:1fr}
  .str-motif{display:none}
  .cat-grid{grid-template-columns:repeat(2,1fr)}
  .prod-grid{grid-template-columns:1fr}
  .news a{grid-template-columns:auto 1fr;row-gap:8px}
  .news .ttl{grid-column:1/-1}
  .news .ar{display:none}
  .offices{grid-template-columns:1fr}
  .access{grid-template-columns:1fr}
  .profile>div{grid-template-columns:1fr;gap:6px}
  .grid-lines{background-size:calc(100%/3) 100%}
  .hero-foot .lead{max-width:none}
  .post-ttl{font-size:clamp(20px,5vw,26px)}
  .post-body img[data-size="small"],.post-body img[data-size="medium"]{width:100%}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
  .rv{opacity:1;transform:none}
  /* JS skips the particle overlay under reduced motion, but this is a
     fail-safe in case it doesn't run at all. */
  .hero-headline .ln>span{opacity:1}
  .hero-title-cv{display:none}
  /* Animations are off, so the intro would just sit there as a blank plate.
     Skip it and let the page start on the hero. */
  .intro{display:none}
  body.intro-on{overflow:auto}
}
