/* hidekiowa-site — global styles.
   Minimal design constraints (see CLAUDE.md): 4 color tokens, 4 font-size
   tokens, block spacing via --edge / --space-block only.
   Motion easing = power2.out相当 = cubic-bezier(0.215, 0.61, 0.355, 1). */

:root{
  /* color — the only 4 allowed */
  --paper:#fbfbfa;
  --ink:#141414;
  --muted:#8a8a86;
  --hair:#e4e4e0;

  /* spacing — gutter + block gap (multiples only) */
  --edge:28px;              /* gutter (gallery gap, side padding) */
  --space-block:84px;       /* header->content block gap = --edge * 3 (SP overrides to 56) */
  --title-gap:calc(var(--edge) * 2); /* title-block -> first content = 56, ALL pages (PC/SP) */
  --backtotop-size:36px;    /* back-to-top button diameter */
  --backtotop-band:calc(var(--edge) * 4 + var(--backtotop-size)); /* content->footer band = 148 (SP 120) */
  --content-narrow:calc((min(100vw, 1500px) - var(--edge) * 4) / 3 * 2 + var(--edge)); /* 3-col gallery's 2 cols + 1 gutter; reading width (interviews/client-work). SP = full */

  /* font-size — the only 4 (px直書き禁止, reference these) */
  --fs-1:11px;              /* footer / caption */
  --fs-2:14px;              /* nav / wordmark / body — 仮値, tune at review */
  --fs-3:18px;              /* page title — 仮値; applied to section pages in 3c */
  --fs-4:64px;              /* display: projects-list titles + home headline (SP 36) */
}

*{ margin:0; padding:0; box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
  background:var(--paper);
  color:var(--ink);
  font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size:var(--fs-2);
  line-height:1.6;
  overflow-x:clip;                 /* contain full-bleed carousel / photo band; no h-scroll */
}
a{ color:inherit; text-decoration:none; }

/* --- header / nav (all lowercase) --- */
header{
  position:sticky; top:0; z-index:10;
  display:flex; justify-content:space-between; align-items:baseline;
  padding:var(--edge);
  background:color-mix(in srgb, var(--paper) 92%, transparent);
}

/* shared glass blur — header + lightbox use the SAME value & format; keep in sync.
   (each element sets its own --paper opacity: header 92%, lightbox 97%.) */
header,
.lightbox{ -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); }
.wordmark{ font-size:var(--fs-2); font-weight:500; letter-spacing:.08em; }
nav{ display:flex; gap:22px; } /* intra-component gap (not block spacing) */
nav a{ font-size:var(--fs-2); color:var(--muted); letter-spacing:.08em; text-transform:lowercase; }
nav a:hover,
nav a[aria-current="page"]{ color:var(--ink); }
.nav-label-short{ display:none; } /* SP-only 'work' abbreviation (toggled at <=760px) */

/* block spacing: header->content and content->footer both = --space-block */
/* header->content = --space-block; content->footer = --backtotop-band (bigger, for the button) */
main{ max-width:1500px; margin:0 auto; padding:var(--space-block) var(--edge) var(--backtotop-band); }

/* title block: header->title = --space-block (main padding-top); title->desc =
   half --edge (intra-block, tight); the LAST title-block element (title, or desc/
   intro when present) -> first content = --title-gap (56, unified all pages) */
.page-title{
  font-size:var(--fs-3); color:var(--ink);
  font-weight:500; letter-spacing:.08em;  /* title = header baseline (6b-fix8; was .02em) */
  margin-bottom:var(--title-gap);       /* title-block -> content (unified, all pages) */
}
/* title -> desc is intra-block (tight); the desc then carries the --title-gap */
.page-title:has(+ .page-desc),
.page-title:has(+ .cw-intro){ margin-bottom:calc(var(--edge) / 2); }
.page-desc, .cw-intro{ margin-bottom:var(--title-gap); }
.page-desc{
  font-size:var(--fs-2); color:var(--muted);
  max-width:36em;                 /* readable measure */
}

/* --- projects list view (template 2): hover full-bleed photo band --- */
.plist{ list-style:none; border-top:1px solid var(--hair); }
.plist li{ position:relative; border-bottom:1px solid var(--hair); }
/* photo band bleeds to the full viewport width; fades in on hover */
.rowbg{
  position:absolute; top:0; bottom:0; left:50%; z-index:0;
  width:100vw; margin-left:-50vw; overflow:hidden;
  opacity:0; pointer-events:none; transition:opacity .4s ease;
}
.rowbg__img{
  position:absolute; inset:0;
  background-size:cover; background-position:center;
  filter:blur(14px); transform:scale(1.12);   /* push the blur bleed off-edge */
}
.rowbg::after{ content:""; position:absolute; inset:0;
  background:color-mix(in srgb, var(--ink) 22%, transparent); } /* scrim for paper text */
.plist li:hover .rowbg{ opacity:1; }
.prow{
  position:relative; z-index:1;
  display:flex; justify-content:space-between; align-items:center; /* mock delta: center (was baseline) */
  gap:var(--edge); padding:calc(var(--edge) * 2) 0;
  text-decoration:none; color:var(--ink); transition:color .4s ease;
}
.prow__title{ font-size:var(--fs-4); font-weight:500; letter-spacing:0; line-height:1.05; } /* display (fs-4) = 0 (6b-fix8; .08em was too loose at 64px) */
.prow__meta{ font-size:var(--fs-1); color:var(--muted); letter-spacing:.08em;
  white-space:nowrap; transition:color .4s ease; }
.plist li:hover .prow,
.plist li:hover .prow__meta{ color:var(--paper); } /* text -> paper over the band */
.prow:focus-visible{ outline:2px solid var(--ink); outline-offset:4px; }

/* --- slideshow型 (zine): peeking carousel, wrap --- */
.slideshow{
  --slide-w: min(var(--content-narrow), 90vw, 72vh * 1.5); /* 3:2 center slide; caps: narrow width / 90vw / 72vh */
  --peek-opacity: 0.3;                       /* prev/next 'sunk into paper' look (tunable) */
  --peek-gap: calc(var(--edge) * 2.5);       /* center<->side gap = 70px (PC; SP tightens to --edge) */
}
.carousel{                                   /* full-viewport-width wrapper: clean edge cut */
  position:relative; left:50%; width:100vw; margin-left:-50vw; overflow:hidden;
}
.carousel__track{ position:relative; height:calc(var(--slide-w) / 1.5); } /* 3:2 */
.carousel__slide{
  position:absolute; top:0; left:50%;
  width:var(--slide-w); margin-left:calc(var(--slide-w) / -2);  /* center rel-0 */
  transform:translateX(calc(var(--rel, 0) * (var(--slide-w) + var(--peek-gap)))); /* step = slide + gap */
  opacity:var(--peek-opacity); cursor:pointer;
  overflow:hidden;                           /* clip the scaled/blurred img -> sharp slide edge */
  transition:none;                           /* enabled once .is-ready (no first-paint jump) */
}
.carousel.is-ready .carousel__slide{ transition:transform .45s ease, opacity .45s ease; }
.carousel.is-ready .carousel__slide img{ transition:filter .45s ease, transform .45s ease; } /* blur+scale ease with opacity */
.carousel__slide.is-center{ opacity:1; cursor:default; } /* center: full, not clickable */
/* peek = frosted glass (= header blur). scale(1.06) pushes the blur bleed past
   the slide's overflow:hidden edge, so the frame stays sharp while the image blurs. */
.carousel__slide img{ width:100%; height:100%; object-fit:contain; display:block; filter:blur(6px); transform:scale(1.06); }
.carousel__slide.is-center img{ filter:blur(0); transform:scale(1); } /* center = sharp, unscaled */
.slideshow__controls{
  display:flex; align-items:center; justify-content:center; gap:var(--edge);
  margin-top:calc(var(--edge) * 2);          /* carousel -> controls */
}

/* --- 行システム (共通: client-work / interviews / info) — a single-column
   reading list at --content-narrow. Opt in with body.rowsys. Each item is a
   .cw-item (border-bottom, first also border-top, padding --edge*2 / SP --edge)
   with a .cw-head > .cw-title (--fs-2/--ink) and a .cw-media below (gap --edge).
   client-work adds desc/meta/notes + images; interviews puts the caption as the
   title with a facade in .cw-media. (Class prefix cw- is historical.) --- */
.rowsys main{ max-width:calc(var(--content-narrow) + var(--edge) * 2); } /* reading width */
/* desc/intro -> list gap comes from the unified --title-gap (.page-desc, .cw-intro) */

/* client-work page exceptions (white ground; built by js/clientwork.js) */
body[data-page="client-work"]{ background:#fff; }           /* page exception: white ground (see CLAUDE.md) */
body[data-page="client-work"] header{ background:color-mix(in srgb, #fff 92%, transparent); } /* glass ground -> #fff base (blur/layout unchanged) */
.cw-intro{                                   /* client-work exception: normal case, not chrome */
  font-size:var(--fs-2); color:var(--muted);
  letter-spacing:normal; text-transform:none; /* margin-bottom = --title-gap (shared rule) */
}
.cw-intro a{ color:var(--ink); text-decoration:underline; text-underline-offset:2px; }
/* rule sits above the first PROJECT (not the header montage): header GIF has no
   line above it; the hairline separates it from UNIQLO UT 2014 onward */
.cw-item:first-of-type{ border-top:1px solid var(--hair); }
.cw-item{ border-bottom:1px solid var(--hair); padding:calc(var(--edge) * 2) 0; } /* row rhythm = projects一覧 .prow (56px) */
.cw-head{ display:flex; flex-wrap:wrap; align-items:baseline; gap:.5em; }
.cw-title{ font-size:var(--fs-2); color:var(--ink); }
.cw-title-link{ color:inherit; text-decoration:none; }        /* tha.jp link — inherits --ink */
.cw-title-link:hover, .cw-title-link:focus-visible{ text-decoration:underline; text-underline-offset:3px; }
.cw-title-ext{ color:var(--muted); }                          /* ↗ same size, muted */
.cw-desc{ font-size:var(--fs-2); color:var(--muted); }        /* desc de-emphasised via colour, no colon */
.cw-meta{ margin-top:6px; font-size:var(--fs-1); color:var(--muted); letter-spacing:.08em; }
.cw-note{ margin-top:4px; font-size:var(--fs-1); color:var(--muted); }
.cw-media{ margin-top:var(--edge); display:flex; flex-direction:column; gap:var(--edge); } /* = gallery gutter */
.cw-header{ margin:0 0 var(--title-gap); }                    /* pulpsamples montage -> list (unified; was --edge*1.5) */
.cw-header-link{ display:block; }                            /* links the header GIF to pulp.jp (no hover effect) */
.cw-header-link:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
.cw-shot{ display:block; width:100%; height:auto; }          /* plain <img>, fills reading column (no lightbox) */
/* poster-less video facade: paper box + centered ▶; iframe injected on click */
.cw-video{
  position:relative; width:100%; aspect-ratio:16 / 9;
  background:color-mix(in srgb, var(--ink) 4%, var(--paper)); /* borderless tile */
  display:flex; align-items:center; justify-content:center;
}
.cw-video.is-playing{ background:#000; }                     /* iframe fills; box recedes */
.cw-video iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
.cw-play svg{ fill:currentColor; }            /* filled ▶ triangle (ctrl-btn sizes to 22px) */
/* poster-FULL facade (interviews): oEmbed thumbnail behind the ▶ */
.cw-video__poster{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.cw-video.has-poster .cw-play{ position:relative; z-index:1; } /* ▶ above the poster */
/* interviews (テンプレート6, js/interviews.js) reuses the 行システム above: each
   video is a .cw-item whose .cw-title is the lowercase caption and .cw-media
   holds one poster-full facade. No interviews-specific row rules needed. */

/* --- info (テンプレート/ページ, 静的 HTML): 行システム + portrait + 名乗り
   ブロック(段組外)+ 本文のみ2段組。正本 = preview/hidekiowa-info-mock-v3.html --- */
body[data-page="info"] .cw-item:first-of-type{ border-top:0; } /* portrait の直下に罫線を引かない (title→portrait gap = 共通 --title-gap) */
/* portrait margin-bottom は 0: portrait->EN名乗り のギャップは最初の .cw-item の
   padding-top(--edge*2)のみ = title->portrait(page-title margin-bottom --edge*2)と同値 */
.portrait{ display:block; width:100%; height:auto; margin-bottom:0; }
/* 名乗りブロック(段組の外) */
.name{ font-size:var(--fs-2); font-weight:500; color:var(--ink); }
.role{ margin-top:4px; font-size:var(--fs-1); color:var(--muted); }
/* 本文のみ2段組(info 例外: 本文は通常表記) */
.prose{
  margin-top:var(--edge);
  line-height:1.9; letter-spacing:normal; text-transform:none;
  column-count:2; column-gap:calc(var(--edge) * 2);
}
.prose p{ break-inside:avoid; }
.prose p + p{ margin-top:1.4em; }
.prose .lede{ color:var(--ink); }             /* 冒頭1文(本文と同じ --ink・意味的フック) */
.jp .prose{ line-height:2.05; }               /* JP は行間を広く */
.prose a{ color:var(--ink); text-decoration:underline; text-underline-offset:2px; } /* 文中リンク */
/* リンク行(全小文字・スラッシュ区切り) */
.links{ font-size:var(--fs-2); color:var(--muted); letter-spacing:.08em; line-height:1.9; } /* line-height = .prose (SP 2-line spacing) */
.links a{ color:var(--ink); text-decoration:none; white-space:nowrap; } /* no break inside a label (e.g. "pulp, inc.") */
.links a:hover, .links a:focus-visible{ text-decoration:underline; text-underline-offset:3px; }
/* slash separators ONLY (inner slashes = group's span children, + the between-group sep).
   NOT .links__group itself — that was the bug: the first group got a .6em left margin
   that pushed "pulp" right of the body text. */
.links__group > span, .links__sep{ margin:0 .6em; color:var(--hair); }
.links__group{ display:inline; }                  /* PC: all one line (look unchanged) */

/* --- home 版面 (mock v4 lottery composition; rows built by js/home.js) --- */
.home{ max-width:1240px; margin:0 auto; }    /* home-specific width (narrower than main 1500) */
.home .row{ display:flex; justify-content:space-between; align-items:flex-start; }
.home .row + .row{ margin-top:150px; }        /* home 版面固定値 (see CLAUDE.md) */
.home .row a{ display:block; }
.home .ph{ display:block; width:100%; height:auto; } /* w/h attrs reserve space (CLS) */
/* home label = 2 lines: path (prefix --muted + name --ink) then years (--muted) */
.home-label{ margin-top:8px; font-size:var(--fs-1); letter-spacing:.08em; }
.home-label__path{ display:block; }
.home-label__prefix{ color:var(--muted); }
.home-label__name{ color:var(--ink); }
.home-label__years{ display:block; color:var(--muted); }

/* --- footer (all pages): hairline + © + social icons (Instagram, Facebook) --- */
footer{
  border-top:1px solid var(--hair);
  padding:var(--edge);
  display:flex; align-items:center; justify-content:space-between;
  color:var(--muted); font-size:var(--fs-1); letter-spacing:.08em;
}
footer .social{ display:flex; align-items:center; gap:16px; } /* intra-component gap */
footer .social a{ color:var(--muted); display:inline-flex; } /* svg inherits via currentColor */
footer .social a:hover,
footer .social a:focus-visible{ color:var(--ink); }
footer .social svg{ width:16px; height:16px; display:block; fill:currentColor; }

/* --- back to top: behavior from kana-site, rebuilt in hidekiowa tokens --- */
.to-top{
  position:fixed; right:var(--edge); bottom:var(--edge); z-index:50;
  width:var(--backtotop-size); height:var(--backtotop-size); border-radius:50%; /* muted filled circle */
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--muted); color:var(--paper); border:none; cursor:pointer;
  opacity:0; transform:translateY(6px); pointer-events:none;
  transition:opacity .3s ease, transform .25s ease, background-color .2s ease, bottom .15s ease-out;
}
.to-top.show{ opacity:1; transform:none; pointer-events:auto; }
.to-top:hover,
.to-top:focus-visible{ background:var(--ink); } /* circle -> --ink; arrow stays --paper (color) */
.to-top svg{ width:16px; height:16px; display:block; } /* --paper arrow (stroke=currentColor) */

/* --- lightbox (gallery型): --paper 0.97 backdrop, token controls --- */
.lightbox{
  position:fixed; inset:0; z-index:100;
  display:flex; align-items:center; justify-content:center;
  background:color-mix(in srgb, var(--paper) 97%, transparent);
  opacity:0; pointer-events:none;
  transition:opacity .3s ease;
}
.lightbox.open{ opacity:1; pointer-events:auto; }
.lightbox__bar{ display:contents; } /* PC: no box; children position individually */
.lightbox__stage{ display:flex; max-width:90vw; max-height:85vh; }
.lightbox__stage img{
  /* reserve a left/right rail each = edge + 44px button + edge, so side arrows
     never overlap the image (PC/tablet). SP overrides back to 90vw (bottom bar). */
  max-width:min(90vw, calc(100vw - 2 * (var(--edge) * 2 + 44px)));
  max-height:85vh; width:auto; height:auto; display:block;
}
/* shared control chrome: circle button + counter (lightbox + zine slideshow) */
.ctrl-btn{
  cursor:pointer; display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px; padding:0; border-radius:50%;  /* 44px circle = visible hit area */
  background:var(--paper); border:1px solid var(--hair); color:var(--muted);
}
.ctrl-btn:not([aria-disabled="true"]):hover,
.ctrl-btn:not([aria-disabled="true"]):focus-visible{ color:var(--ink); } /* glyph only */
.ctrl-btn[aria-disabled="true"]{ color:var(--hair); cursor:default; }      /* clamped end (zine) */
.ctrl-btn svg{ width:22px; height:22px; display:block; }
.ctrl-counter{ font-size:var(--fs-1); color:var(--muted); letter-spacing:.08em; }

.lightbox button{ position:absolute; }        /* appearance from .ctrl-btn */
.lightbox__close{ top:var(--edge); right:var(--edge); }
.lightbox__prev{ left:var(--edge); top:50%; transform:translateY(-50%); }
.lightbox__next{ right:var(--edge); top:50%; transform:translateY(-50%); }
.lightbox__counter{ position:absolute; bottom:var(--edge); left:50%; transform:translateX(-50%); }

/* --- Masonry gallery (column count owned by js/gallery.js) --- */
.gallery{ display:flex; gap:var(--edge); }
.gallery__col{ flex:1; min-width:0; display:flex; flex-direction:column; gap:var(--edge); }
/* each item is a native <button> (focusable) wrapping the image */
.gallery__item{
  display:block; width:100%; padding:0; border:none; background:none;
  cursor:pointer; font:inherit; color:inherit;
}
.gallery__item:focus-visible{ outline:2px solid var(--ink); outline-offset:2px; }
/* width/height attrs on <img> reserve aspect-ratio space -> no CLS on lazy load */
.gallery img{ display:block; width:100%; height:auto; }

/* --- reveal motion: white -> monochrome (appear) -> color (grayscale) --- */
.reveal{
  opacity:0;
  transform:translateY(18px);
  filter:grayscale(1);
  transition:
    opacity   .6s cubic-bezier(0.215, 0.61, 0.355, 1),  /* appear: power2.out */
    transform .6s cubic-bezier(0.215, 0.61, 0.355, 1),  /* appear: power2.out */
    filter     3s cubic-bezier(0.55, 0.055, 0.675, 0.19); /* color: power2.in (holds mono, then blooms) */
}
.reveal.is-visible{ opacity:1; transform:none; filter:grayscale(0); }

@media (prefers-reduced-motion: reduce){
  .reveal{ opacity:1; transform:none; filter:none; transition:none; }
  .to-top{ transform:none; transition:none; } /* no slide/fade movement */
  .lightbox{ transition:none; }
  .rowbg{ transition:none; }              /* projects: instant band (photo/blur kept) */
  .prow, .prow__meta{ transition:none; } /* instant text-color switch */
  .carousel.is-ready .carousel__slide,
  .carousel.is-ready .carousel__slide img{ transition:none; } /* zine: instant reposition + blur switch */
}

/* --- SP (<=760px): gallery.js rebuilds to 1 column; block gap tightens --- */
@media (max-width:760px){
  :root{
    --space-block:56px;                                            /* --edge * 2 */
    --title-gap:calc(var(--edge) * 1.5);                           /* title-block -> content = 42 on SP (PC 56) */
    --backtotop-band:calc(var(--edge) * 3 + var(--backtotop-size)); /* content->footer band = 120 */
    --fs-4:36px;                                                   /* display size on SP */
  }
  .nav-label-full{ display:none; }   /* SP: 'client work' -> 'work' (fits 320px) */
  .nav-label-short{ display:inline; }

  /* gallery 1-col vertical gutter: 42px block rhythm (was --edge=28) */
  .gallery__col{ gap:calc(var(--edge) * 1.5); }

  /* 行システム (client-work / interviews / info): content-narrow collapses too
     far on SP -> full width; row padding = --edge*1.5 (42px block rhythm) so
     content->hairline / hairline->content are both 42 (hairline itself unchanged) */
  .rowsys main{ max-width:none; }
  .cw-item{ padding:calc(var(--edge) * 1.5) 0; }
  .prose{ column-count:1; }              /* info: single column on SP */
  /* info link row: fixed 2 lines on SP (group1 / group2); hide the between-group slash */
  .links__group{ display:block; }
  .links__sep{ display:none; }

  /* projects list: text only, meta stacked under title; no photo band on touch */
  .prow{ flex-direction:column; align-items:flex-start; gap:8px; padding:var(--edge) 0; }
  .rowbg{ display:none; }
  .plist li:hover .prow{ color:var(--ink); }         /* keep readable if :hover sticks on tap */
  .plist li:hover .prow__meta{ color:var(--muted); }

  .slideshow{ --slide-w: 84vw; --peek-gap: var(--edge); } /* zine: wide center, thin peeks, tighter gap */

  /* home 版面 SP: single stack, 82% width, even rows right-aligned (mock v4) */
  .home .row{ flex-direction:column; gap:72px; margin-left:0 !important; margin-right:0 !important; }
  .home .row + .row{ margin-top:72px; }
  .home .row a{ width:82% !important; margin-top:0 !important; } /* !important beats home.js inline width */
  .home .row a:nth-child(even){ align-self:flex-end; }

  /* SP lightbox — follows kana .lightbox-info: a full-width bottom flex bar with
     the counter growing (flex:1, centered) so prev pins to the left edge and
     next to the right edge; vertically centered. close stays top-right. */
  .lightbox__bar{
    display:flex; align-items:center; gap:var(--edge);
    position:absolute; bottom:var(--edge); left:var(--edge); right:var(--edge);
  }
  .lightbox__stage img{ max-width:90vw; } /* SP: controls are bottom, no side rails */
  /* scope under .lightbox__bar (0,2,0) to outrank base `.lightbox button` (0,1,1) */
  .lightbox__bar .lightbox__prev,
  .lightbox__bar .lightbox__next,
  .lightbox__bar .lightbox__counter{
    position:static; transform:none; top:auto; right:auto; left:auto; bottom:auto;
  }
  .lightbox__bar .lightbox__counter{ flex:1; text-align:center; } /* grows -> arrows to edges */
}
