/* Goyo Club — styles
   Mono + slab classical. Single-row GNB, generous header→body gap,
   no card/grid borders, decorative vertical guide lines on page bg.
*/

@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&family=Roboto+Slab:wght@400;500;700&display=swap');

* { box-sizing: border-box; }
html, body, #root { margin: 0; padding: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  font-size: var(--t-base);
  line-height: 1.45;
  letter-spacing: 0.01em;
  -webkit-font-smoothing: antialiased;
  text-transform: uppercase;
}
button { font: inherit; color: inherit; background: transparent; border: 0; padding: 0; cursor: pointer; text-transform: inherit; }
button:disabled { cursor: not-allowed; }
input { font: inherit; color: inherit; background: transparent; border: 0; outline: 0; text-transform: inherit; }

/* ----- App shell ----- */
.app {
  position: relative;
  height: 100vh;
  display: grid;
  grid-template-rows: var(--gnb-h) 1fr var(--footer-h);
  background: var(--bg);
  color: var(--fg);
}
.split { margin-top: var(--header-gap); }

/* ----- Decorative page-background vertical guides ----- */
.page-guides {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.page-guides__line {
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: var(--fg);
  opacity: 0.06;
  /* Loading parallax: each line starts at the page's left edge (left: 0)
     and slides to its inline `--target-left` with a magnetic ease. The
     cubic-bezier overshoots `1` slightly so the line snaps past its target
     and settles back, giving the magnetic feel. `--guide-delay` and
     `--guide-duration` are set per line for parallax layering. */
  animation: guide-fly-in var(--guide-duration, 5500ms) cubic-bezier(0.22, 1.05, 0.36, 1) both;
  animation-delay: var(--guide-delay, 0ms);
}
.page-guides__line--rail { opacity: 0.10; }
@keyframes guide-fly-in {
  from { left: 0; }
  to   { left: var(--target-left, 0); }
}

/* ----- GNB top: single row spanning full width ----- */
.gnb-top {
  position: relative;
  z-index: 5;
  display: grid;
  grid-template-columns: 1fr var(--gnb-center-w) 1fr;
  align-items: start;
  padding: var(--sp-md) var(--gutter) 0 var(--gutter);
}
.gnb-top__left { display: flex; flex-direction: column; gap: var(--sp-sm); min-width: 0; }
.gnb-top__center { display: flex; align-items: center; justify-content: center; padding-top: 2px; }
.gnb-top__right { display: flex; align-items: flex-start; justify-content: flex-end; }

/* logo */
.logo { display: flex; align-items: center; justify-content: center; }
.logo__img {
  display: block;
  height: var(--size-btn);
  width: 40px;
  object-fit: contain;
  flex: 0 0 auto;
  animation: logo-spin 12s linear infinite;
  transform-origin: 50% 50%;
}
.logo:hover .logo__img { animation-play-state: paused; }
@keyframes logo-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
html[data-theme="dark"] .logo__img { filter: invert(1); }

/* GNB right — page navigation (ABOUT / SERVICE / CONTACT). Active page gets
   underline; underline only on the .btn-label so brackets/whitespace stay clean. */
.gnb-right { display: flex; gap: var(--sp-lg); padding-top: 4px; }
.gnb-right__link {
  color: var(--fg);
  letter-spacing: 0.06em;
  cursor: pointer;
}
.gnb-right__link:hover .btn-label,
.gnb-right__link--active .btn-label {
  text-decoration: underline;
  text-underline-offset: 1px;
}

/* GNB-left Back button (shown on static pages instead of TopTabs). */
.gnb-back {
  letter-spacing: 0.04em;
  color: var(--fg);
  cursor: pointer;
  padding-top: 4px;
}
.gnb-back:hover .btn-label {
  text-decoration: underline;
  text-underline-offset: 1px;
}

/* GNB left tabs (top row) */
.top-tabs {
  display: inline-flex; align-items: baseline; gap: 8px; padding-top: 4px;
  flex-wrap: wrap;
}
.top-tab {
  letter-spacing: 0.04em;
  color: var(--fg);
  position: relative;
  padding: 0;
}
.filter-count {
  font-size: var(--t-xs);
  margin-left: 2px;
  color: var(--fg);
  vertical-align: super;
  letter-spacing: 0.04em;
}
.top-tab__sep { color: var(--fg); padding: 0 2px; user-select: none; }
.top-tab:hover .top-tab__label { text-decoration: underline; text-underline-offset: 1px; }
.top-tab--active .top-tab__label { text-decoration: underline; text-underline-offset: 1px; }

.top-tabs__search-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 4px; margin-left: 2px;
  color: var(--fg); cursor: pointer;
}
.top-tabs__search-btn:hover { transform: scale(1.05); }
.top-tabs__search-icon { display: block; width: 13px; height: 13px; }

/* Series chips row */
.series-row {
  display: flex; gap: var(--sp-md); align-items: center;
  height: var(--size-chip);
}
.series-row__chips { display: flex; gap: var(--sp-md); align-items: center; }
.chip {
  letter-spacing: 0.04em; color: var(--fg);
  white-space: nowrap; flex-shrink: 0;
}
.chip:hover .chip__label { text-decoration: underline; text-underline-offset: 1px; }
.chip--active .chip__label { text-decoration: underline; text-underline-offset: 1px; }

/* ----- Split (body) ----- */
.split {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--split-cols, 1.5fr 1fr);
  min-height: 0;
  overflow: hidden;
}

/* ----- Static pages (About / Service / Contact) — centered 40vw body ----- */
.static-page {
  position: relative;
  z-index: 1;
  margin-top: var(--header-gap);
  display: flex;
  justify-content: center;
  overflow-y: auto;
  min-height: 0;
  padding: 0 var(--gutter);
}
.static-page > .rbody {
  width: 40vw;
  flex: 0 0 40vw;
}

/* Service page — wider gap between label and description for readability */
.rbody--service .kv {
  gap: var(--sp-xl);
  align-items: baseline;
}

/* ----- Contact form ----- */
/* KV row that holds an input/textarea on the right (text-align: left so typed
   content reads naturally, while the row layout stays right-anchored).
   Selectors use `.kv.kv--form` (compound) so they win over the unified
   `.kv` rule that lives later in this file (single-class specificity tie
   would let the unified rule override otherwise). Spacing is generous:
   padding 10px (inter-row gap = 20px, ~2.5× of base 8px) and horizontal
   gap 64px (~2.7× of base 24px). */
.kv.kv--form,
.kv.kv--radios {
  padding: var(--sp-row) 0;
  min-height: 36px;
  gap: var(--sp-2xl);
}
.kv.kv--form-multiline,
.kv.kv--radios {
  align-items: flex-start;
}
.kv.kv--form .kv__v { flex: 1; min-width: 0; text-align: left; }

.form-input {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--fg);
  font: inherit;
  letter-spacing: inherit;
  padding: 0 0 4px 0;
  outline: none;
}
.form-input::placeholder {
  color: var(--fg-dim);
  text-transform: none;
  letter-spacing: 0.02em;
}
.form-input:focus { border-bottom-color: var(--fg); }

.form-input--textarea {
  min-height: 60px;
  resize: vertical;
  /* padding-top: 0 so textarea's first line aligns with the label's
     first line (single-line input has 0 padding-top too). */
  padding: 0 0 4px 0;
  line-height: 1.45;
}

/* Radio row — vertical stack on the right, underline on hover/active.
   (align-items handled in the .kv.kv--radios rule above for specificity.) */
.form-radios {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-end;
}
.form-radio {
  letter-spacing: 0.04em;
  color: var(--fg);
  cursor: pointer;
  padding: 0;
  background: transparent;
  border: 0;
}
.form-radio:hover .btn-label,
.form-radio--active .btn-label {
  text-decoration: underline;
  text-underline-offset: 1px;
}

.form-submit {
  display: flex;
  justify-content: flex-end;
  padding: var(--sp-row) 0;
  min-height: 36px;
}

/* ----- Left pane ----- */
.left {
  display: grid;
  grid-template-rows: 1fr;
  min-height: 0;
  min-width: 0;
  background: transparent;
  padding-left: var(--gutter);
  padding-right: var(--gnb-center-w);
}

/* ----- Index ----- */
/* Char-stagger variables hoisted to .index so both row characters and the
   controls row (LOAD MORE / RESET ALL) inherit them and stay on a single
   global typewriter timeline. */
.index {
  display: grid;
  grid-template-rows: 1fr;
  min-height: 0;
  --char-stagger: 2.5ms;
  --intro-delay: 80ms;
}
.index__controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 0 24px 0;
  /* Controls fade in right after the last row's last char.
     `--char-i` is set inline by LeftPane to the total char count. */
  opacity: 0;
  animation: char-pop 1ms forwards;
  animation-delay: calc(var(--char-i, 0) * var(--char-stagger) + var(--intro-delay));
}
.load-more {
  letter-spacing: 0.08em;
  font-size: var(--t-base);
  padding: 2px 0;
  color: var(--fg);
}
.index__header {
  display: grid;
  grid-template-columns: 88px 1fr 240px 100px;
  padding: 0 0 6px 0;
  color: var(--fg-dim);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.index__scroll {
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
.index__empty { padding: 16px 0; color: var(--fg-dim); }

/* row */
.row {
  display: grid;
  grid-template-columns: 88px 180px 1fr 200px 100px;
  padding: 4px 0;
  min-height: var(--row-h);
  align-items: center;
  position: relative;
  cursor: pointer;
  user-select: none;
}
/* Per-character typewriter entry. Each .cell-char gets a global --char-i
   from JSX (computed across rows); CSS schedules its pop-in via
   `var(--char-i) * char-stagger`. Single shared timeline → characters reveal
   strictly left-to-right, top row to bottom row. The same timeline drives
   `.index__controls` (LOAD MORE / RESET ALL) so they fade in right after
   the last row's last char.
   Variables `--char-stagger` and `--intro-delay` are hoisted to .index. */
.row--enter .cell-char {
  opacity: 0;
  animation: char-pop 1ms forwards;
  animation-delay: calc(var(--char-i, 0) * var(--char-stagger) + var(--intro-delay));
}
@keyframes char-pop {
  to { opacity: 1; }
}
.row .cell { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 12px; }
.row .cell:last-child { padding-right: 0; text-align: right; }
@keyframes blink { 50% { opacity: 0; } }

/* hero / pinned — no border, just slight emphasis */
.row--pinned { font-weight: 700; }
.row--pinned .cell:first-child { font-family: var(--slab); letter-spacing: 0.18em; }

/* Hero row: presentational, never interactive. Override any hover/select. */
.row--hero.row--static { cursor: default; }
.row--hero.row--static:hover { background: transparent !important; color: var(--fg) !important; }
.row--hero.row--static:hover .cell-text { background: transparent !important; color: var(--fg) !important; }

/* hover/select treatments
   INVERT: per-cell-text inline highlight — black bar sits flush with glyph
   height and ends exactly at the text edges, never the row gutter. */
.row--hover-invert:not(.row--selected) .cell-text {
  background: var(--invert-bg);
  color: var(--invert-fg);
  padding: 2px 4px;
  margin: -2px -4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.row--selected-invert .cell-text {
  background: var(--invert-bg);
  color: var(--invert-fg);
  padding: 2px 4px;
  margin: -2px -4px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

.row--hover-underline:not(.row--selected) .cell-text { box-shadow: inset 0 -1px 0 var(--fg-dim); }
.row--selected-underline { font-weight: 700; }
.row--selected-underline .cell-text { box-shadow: inset 0 -2px 0 var(--fg); }

.row--hover-marker { padding-left: 14px; }
.row--hover-marker::before {
  content: "›"; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  color: var(--fg-dim);
}
.row--selected-marker { font-weight: 700; padding-left: 14px; }
.row--selected-marker::before { content: "▸"; color: var(--fg); position: absolute; left: 0; top: 50%; transform: translateY(-50%); }

/* ----- Right pane ----- */
.right {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  min-width: 0;
  background: transparent;
  overflow: hidden;
  padding-left: var(--gnb-center-w);
  padding-right: var(--gutter);
}
.right__chrome {
  display: flex; justify-content: flex-end; align-items: center;
  height: var(--size-chip);
  margin-bottom: 6px;
}
.reset-btn {
  letter-spacing: 0.08em;
  font-size: var(--t-base);
  padding: 2px 0;
  color: var(--fg);
  cursor: pointer;
}
.reset-btn:hover .btn-label { text-decoration: underline; text-underline-offset: 1px; }

/* Body scroll area — scrollbar hidden by default, appears only while scrolling.
   `.right__body--scrolling` toggle is driven by a JS scroll listener that
   adds the class on scroll and removes after a short timeout. */
.right__body {
  overflow-y: scroll;
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
  transition: scrollbar-color 200ms ease;
}
.right__body--scrolling { scrollbar-color: var(--line) transparent; }
.right__body::-webkit-scrollbar { width: 8px; background: transparent; }
.right__body::-webkit-scrollbar-track { background: transparent; }
.right__body::-webkit-scrollbar-thumb {
  background: transparent;
  transition: background 200ms ease;
}
.right__body--scrolling::-webkit-scrollbar-thumb { background: var(--line); }

/* transitions */
.right-phase { transition: opacity 180ms ease, transform 180ms ease; }
.right-phase--fade.right-phase--in { opacity: 1; }
.right-phase--fade.right-phase--out { opacity: 0; }
.right-phase--slide.right-phase--in { opacity: 1; transform: translateY(0); }
.right-phase--slide.right-phase--out { opacity: 0; transform: translateY(8px); }

/* ===== Unified body structure =====
   Each row-like section uses the same vertical rhythm as the index .row
   (min-height 22px + 4px top/bottom padding = 30px). No section gaps,
   no horizontal divider lines. */
.rbody {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Row-like rhythm shared by every body section that holds inline content */
.rbody__header,
.rbody__tags,
.rbody__cta-row,
.kv {
  min-height: var(--row-h);
  padding: 4px 0;
}

/* 1. Header — title (left) ↔ CTA (right) */
.rbody__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
}
.rbody__title {
  font-family: var(--mono);
  font-size: var(--t-base);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* CTA button — button component pattern */
.rbody__cta {
  letter-spacing: 0.08em;
  font-size: var(--t-base);
  padding: 2px 0;
  color: var(--fg);
  cursor: pointer;
  background: transparent;
  border: 0;
  white-space: nowrap;
  flex-shrink: 0;
}
.rbody__cta:hover .btn-label { text-decoration: underline; text-underline-offset: 1px; }

/* 2. Hero media — image / iframe wrapper. Not row-like.
   Asymmetric padding: above = 50% of below (12px / 24px) so the header
   sits noticeably closer to the frame than the next-section content does.
   Applies to every body using .rbody (home right pane + About / Service).
   No `overflow: hidden` — plain <img> children render at native aspect. */
.rbody__hero {
  width: 100%;
  padding: 12px 0 24px;
}
.rbody__hero > img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}

/* 3. Tag chips — left-aligned, clickable. Click toggles tagFilter on the
   left index. Underline on hover/active sits only under the label, not the
   surrounding `[ ` `]` brackets (button component pattern). */
.rbody__tags {
  display: flex;
  align-items: baseline;
  gap: var(--sp-sm);
  flex-wrap: wrap;
  letter-spacing: 0.06em;
}
.rbody__tag {
  color: var(--fg);
  cursor: pointer;
}
.rbody__tag:hover .btn-label,
.rbody__tag--active .btn-label {
  text-decoration: underline;
  text-underline-offset: 1px;
}

/* 4. Info — KV pairs, field name ↔ data (right-aligned), no separators */
.rbody__info { display: flex; flex-direction: column; }
.kv {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
}
.kv__k { color: var(--fg); letter-spacing: 0.1em; flex-shrink: 0; }
.kv__v { color: var(--fg); text-align: right; }
.kv__v--paragraphs { display: flex; flex-direction: column; gap: 8px; }
.kv__v--paragraphs p { margin: 0; text-wrap: pretty; }

/* 5. CTA repeat — right-aligned */
.rbody__cta-row {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

/* 6. Spacer — visible end-of-content gap before site footer */
.rbody__spacer { height: 80px; }

/* 7. Site footer — fixed at app's bottom row, like the gnb header at top.
   No border, padding matches gnb-top gutters so the footer aligns
   horizontally with the rest of the layout. */
.site-footer {
  position: relative;
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 var(--gutter);
  letter-spacing: 0.08em;
  font-size: var(--t-base);
}
.site-footer__copy { color: var(--fg); }
.site-footer__links { display: flex; gap: 16px; }
.site-footer__link {
  color: var(--fg);
  letter-spacing: 0.08em;
  font-size: var(--t-base);
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  text-decoration: none;
}
.site-footer__link:hover .btn-label { text-decoration: underline; text-underline-offset: 1px; }

/* ----- HERO intro paragraphs — inherit body's mono 11px uppercase.
   Each paragraph uses the same vertical rhythm as an index row
   (padding 4px 0 + min-height var(--row-h)) so paragraph spacing matches
   the index's row spacing. */
.rbody__intro { display: flex; flex-direction: column; }
.rbody__intro p {
  margin: 0;
  padding: 4px 0;
  min-height: var(--row-h);
  text-wrap: pretty;
}

/* ----- HERO video frame ----- */
.hero-video { position: relative; width: 100%; aspect-ratio: 16/9; overflow: hidden; background: transparent; }
.hero-video__el { position: absolute; left: -1px; top: -1px; width: calc(100% + 2px); height: calc(100% + 2px); display: block; border: 0; }
/* Ken-burns kicks in only if src is video/img — kept for future iframe→video swap */
.hero-video__el:not(iframe) { object-fit: cover; animation: hero-kenburns 18s ease-in-out infinite alternate; }
@keyframes hero-kenburns {
  from { transform: scale(1.04) translate(0, 0); }
  to   { transform: scale(1.10) translate(-2%, -1%); }
}
.hero-live-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #ff3b30;
  box-shadow: 0 0 6px rgba(255, 59, 48, 0.6);
  vertical-align: middle;
  margin: 0 2px 1px;
  animation: blink 1s steps(1) infinite;
}

/* ----- ARCHIVE (youtube) ----- */
.ytwrap { position: relative; aspect-ratio: 16/9; background: #000; }
.ytwrap__iframe { width: 100%; height: 100%; border: 0; }
.ytwrap__overlay-mark {
  position: absolute; right: 12px; top: 12px;
  width: 56px; height: 56px; border-radius: 50%;
  background: #fff; color: #000;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.ytwrap__mark-inner { font-family: var(--mono); font-size: 9px; font-weight: 700; text-align: center; line-height: 1; }

/* ----- SHOP size selector (KV value override — buttons render right-aligned) ----- */
.sizes { display: flex; gap: 6px; justify-content: flex-end; }
.size { padding: 2px 8px; }
.size--on { background: var(--invert-bg); color: var(--invert-fg); }

/* ----- scrollbar ----- */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--line); }
::-webkit-scrollbar-track { background: transparent; }

/* ----- Search modal ----- */
.search-modal {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(0, 0, 0, 0.72);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  display: flex; align-items: center; justify-content: center;
  padding: 0 var(--gutter);
  animation: search-fade 200ms ease forwards;
}
@keyframes search-fade { from { opacity: 0; } to { opacity: 1; } }
.search-modal__inner {
  width: 100%; max-width: 1100px;
  display: flex; flex-direction: column; gap: 28px;
  color: #fff;
  position: relative;
}
.search-modal__close {
  position: absolute; top: -56px; right: 0;
  color: #fff; letter-spacing: 0.1em; font-family: var(--mono); font-size: var(--t-base);
  cursor: pointer;
}
.search-modal__close:hover .btn-label { text-decoration: underline; text-underline-offset: 1px; }
.search-modal__field {
  display: flex; align-items: center; gap: 18px;
  border-bottom: 1px solid rgba(255,255,255,0.4);
  padding: 18px 4px;
}
.search-modal__icon { color: #fff; flex: 0 0 auto; }
.search-modal__input {
  flex: 1 1 auto;
  background: transparent;
  color: #fff;
  font-family: var(--slab);
  font-size: 40px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 400;
  caret-color: #fff;
  padding: 0;
}
.search-modal__input::placeholder { color: rgba(255,255,255,0.45); font-weight: 400; }
.search-modal__results { display: flex; flex-direction: column; gap: var(--sp-md); max-height: 50vh; overflow-y: auto; }
.search-modal__count { color: rgba(255,255,255,0.55); letter-spacing: 0.14em; font-size: 10px; }
.search-modal__list { display: flex; flex-direction: column; }
.search-modal__row {
  display: grid; grid-template-columns: 88px 1fr 100px;
  gap: 16px;
  padding: var(--sp-sm) var(--sp-xs);
  text-align: left;
  color: #fff;
  border-top: 1px solid rgba(255,255,255,0.12);
  cursor: pointer;
}
.search-modal__row:last-child { border-bottom: 1px solid rgba(255,255,255,0.12); }
.search-modal__row:hover { background: rgba(255,255,255,0.06); }
.search-modal__row-type { letter-spacing: 0.1em; color: rgba(255,255,255,0.6); }
.search-modal__row-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-modal__row-date { color: rgba(255,255,255,0.6); text-align: right; }
