/* ═══════════════════════════════════════════════════════════════
   1 OAK TOKYO — One Of A Kind
   Warm near-black · gold · editorial serif · cinematic
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* palette — warm, never pure black */
  --espresso: #0E0B08;
  --coffee:   #14100C;
  --chocolate:#1A140E;
  --panel:    #221A12;
  --gold:     #C9A45C;
  --gold-hi:  #E6C88A;
  --amber:    #A87938;
  --cream:    #F2ECE1;
  --cream-dim:#B9AC97;
  --taupe:    #6E5A45;
  --line:     rgba(201, 164, 92, .22);
  --line-dim: rgba(201, 164, 92, .12);

  --serif: "Bodoni Moda", "Shippori Mincho", serif;
  --sans:  "Jost", "Zen Kaku Gothic New", sans-serif;

  --ambient: var(--espresso);

  --ease-out: cubic-bezier(.19, 1, .22, 1);
  --ease-luxe: cubic-bezier(.65, .05, 0, 1);

  --gutter: clamp(1.25rem, 4vw, 4.5rem);
}

body[data-lang="ja"] {
  --serif: "Shippori Mincho", "Bodoni Moda", serif;
  --sans:  "Zen Kaku Gothic New", "Jost", sans-serif;
}

/* ── reset ────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* smooth scrolling is provided by Lenis (JS); native smooth would fight it */
html, body { height: auto; }
body {
  background: var(--ambient);
  color: var(--cream);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  transition: background-color 1.4s ease;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: 0; color: inherit; cursor: pointer; }
::selection { background: rgba(201,164,92,.35); color: var(--cream); }

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* film grain over everything */
body::after {
  content: "";
  position: fixed; inset: -50%;
  width: 200%; height: 200%;
  pointer-events: none;
  z-index: 90;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 9s steps(10) infinite;
}
@keyframes grain {
  0%,100% { transform: translate(0,0); } 10% { transform: translate(-3%,2%); }
  30% { transform: translate(2%,-3%); } 50% { transform: translate(-2%,-2%); }
  70% { transform: translate(3%,2%); } 90% { transform: translate(-1%,3%); }
}

/* focus */
:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 4px;
  border-radius: 1px;
}

/* ── buttons ──────────────────────────────────────────── */
.btn {
  position: relative;
  display: inline-block;
  padding: 1.05em 2.4em;
  font-family: var(--sans);
  font-size: .72rem;
  font-weight: 400;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--cream);
  border: 1px solid var(--line);
  overflow: hidden;
  cursor: pointer;
  transition: color .45s var(--ease-out), border-color .45s var(--ease-out), transform .2s var(--ease-out);
}
.btn::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(120deg, var(--amber), var(--gold) 55%, var(--gold-hi));
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .5s var(--ease-luxe);
  z-index: -1;
}
.btn:hover::before, .btn:focus-visible::before { transform: scaleY(1); }
.btn:hover, .btn:focus-visible { color: var(--espresso); border-color: var(--gold); }
.btn:active { transform: scale(.975); }
.btn--gold { border-color: var(--gold); color: var(--gold-hi); }
.btn--ghost { border-color: var(--line-dim); color: var(--cream-dim); }
.btn--ghost:hover { color: var(--espresso); }

/* ── stamps (section timestamps) ──────────────────────── */
.stamp {
  display: flex; align-items: center; gap: 1.1rem;
  font-size: .68rem; font-weight: 400;
  letter-spacing: .34em;
  color: var(--cream-dim);
  text-transform: uppercase;
}
.stamp__time {
  font-family: var(--serif);
  font-size: 1.05rem; font-weight: 500;
  letter-spacing: .18em;
  color: var(--gold);
}
.stamp__rule {
  width: clamp(2.5rem, 6vw, 5.5rem); height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
  transform-origin: left;
}


/* ── SERIF STROKE RENDERING ───────────────────────────── */
/* Bodoni Moda is a VARIABLE font with an `opsz` (optical size) axis, 6–96.
   Browsers map it from font-size automatically and pick the DISPLAY cut, whose
   hairlines are the thinnest the family draws. On iOS those fell under one
   device pixel and vanished: the "+" in "100+" lost its crossbar and read as
   "|", and the bars of A / F / t disappeared unless zoomed.
   `-webkit-font-smoothing` was tried first and did NOT fix it — smoothing only
   affects antialiasing, it cannot thicken a stroke the font drew thin. The
   working fix is forcing a LOW opsz (the text cut) on small serif text, which is
   also the typographically correct choice at these sizes. Large headings keep
   the display cut on purpose: at 3rem+ the hairlines are thick enough to survive
   and the fine contrast is the whole point of a didone. */
.stamp__time, .preloader__count, .menu__link,
.hero__title, .archive__title, .archive__count > span:first-child,
.atile span, .archive__outro-line,
.house__title, .house__body, .house__sub, .house__fact em,
.nights__title, .ncard__day, .reserve__title, .rform__done,
.list__line, .lform__done, .foot__sign {
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
}

/* small serif text → text cut, so hairlines survive at phone sizes */
.stamp__time, .preloader__count, .atile span, .house__fact em,
.house__sub, .rform__done, .lform__done, .list__line, .ncard__day {
  font-variation-settings: "opsz" 8;
}
/* the count sits at ~35px — a mid opsz keeps some elegance while giving the
   "+" a crossbar that actually renders */
.archive__count > span:first-child { font-variation-settings: "opsz" 12; }

/* Headings keep the display cut on DESKTOP, where they're 37–144px and the fine
   hairlines are the point of a didone. On phones the same clamps collapse to
   their minimums — .house__title falls to 27px and .house__body to 22px — and at
   those sizes the display cut's crossbars on A / F / t stop rendering. Below the
   900px breakpoint every serif heading drops to the text cut. */
@media (max-width: 900px) {
  .hero__title, .archive__title, .archive__outro-line,
  .house__title, .house__body,
  .nights__title, .reserve__title, .foot__sign, .menu__link,
  .archive__count > span:first-child {
    font-variation-settings: "opsz" 10;
  }
}

/* ═══════════ PRELOADER ═══════════ */
.preloader {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  background: var(--espresso);
}
/* NOTE: deliberately does NOT set visibility here. index.html's inline critical
   CSS keeps .preloader__inner visibility:hidden, and the preloader JS reveals it
   (gsap.set) only AFTER the intro timeline has snapped the kicker/wordmark/sub to
   opacity:0 — so the content never flashes as unstyled text (pre-main.css) and
   the logo never blinks at full opacity before the fade-in. Re-adding
   visibility:visible here brings the blink back. */
.preloader__inner { position: relative; z-index: 2; text-align: center; }
.preloader__kicker {
  font-size: 1.1rem; letter-spacing: .4em; color: var(--cream-dim);
  margin-bottom: 2rem; text-transform: uppercase;
}
.preloader__wordmark {
  display: block;
  width: min(360px, 68vw); height: auto;
  margin: 0 auto;
}
.preloader__rule {
  width: min(320px, 60vw); height: 1px; margin: 1.5rem auto;
  background: var(--line-dim); overflow: hidden;
}
.preloader__rule span {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--amber), var(--gold-hi));
  transform: scaleX(0); transform-origin: left;
}
.preloader__sub {
  font-size: 1.05rem; letter-spacing: .42em; color: var(--gold);
  text-transform: uppercase;
}
.preloader__count {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: -4.4rem;
  font-family: "Bodoni Moda", serif; font-style: italic;
  font-size: 1rem; color: var(--taupe); letter-spacing: .2em;
}
.preloader__curtain {
  position: absolute; left: 0; width: 100%; height: 50.5%;
  background: var(--espresso); z-index: 1;
}
.preloader__curtain--a { top: 0; }
.preloader__curtain--b { bottom: 0; }

/* ═══════════ CURSOR ═══════════ */
.cursor { position: fixed; top: 0; left: 0; z-index: 110; pointer-events: none; opacity: 0; }
.cursor__dot, .cursor__ring {
  position: fixed; top: 0; left: 0; border-radius: 50%;
  transform: translate(-50%, -50%);
}
.cursor__dot { width: 5px; height: 5px; background: var(--gold-hi); }
.cursor__ring {
  width: 34px; height: 34px;
  border: 1px solid rgba(201,164,92,.45);
  transition: width .35s var(--ease-out), height .35s var(--ease-out), border-color .35s;
}
body.cursor-on { cursor: none; }
body.cursor-on a, body.cursor-on button, body.cursor-on input,
body.cursor-on select, body.cursor-on textarea, body.cursor-on label { cursor: none; }
.cursor.is-hover .cursor__ring {
  width: 56px; height: 56px; border-color: var(--gold);
}
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

/* ═══════════ NAV ═══════════ */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  gap: 2rem;
  padding: 1.1rem var(--gutter);
  transition: background-color .6s ease, backdrop-filter .6s ease, padding .5s var(--ease-out), border-color .6s;
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: rgba(14, 11, 8, .78);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom-color: var(--line-dim);
  padding-top: .8rem; padding-bottom: .8rem;
}
.nav__logo img { height: 38px; width: auto; }
.nav__logo { display: block; transition: opacity .3s; }
.nav__logo:hover { opacity: .75; }
.nav__links { display: flex; gap: 2.6rem; }
.nav__link {
  position: relative;
  font-size: .7rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cream-dim);
  padding: .35em 0;
  transition: color .35s;
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: right;
  transition: transform .45s var(--ease-luxe);
}
.nav__link:hover { color: var(--cream); }
.nav__link:hover::after { transform: scaleX(1); transform-origin: left; }
.nav__right { display: flex; align-items: center; gap: 1.6rem; }
.nav__cta { padding: .8em 1.8em; }
.nav__lang {
  display: flex; gap: .45em; align-items: baseline;
  /* Fixed at the midpoint of the old EN (.68rem) / JA (.88rem) sizes, client-
     directed 2026-07-27 — the toggle used to visibly grow when switching to
     Japanese. Removed from the tier-3 JA list below so it stays this size in
     both languages; letter-spacing is left per-language (tracking is a
     legibility choice for the script, not really "size"). */
  font-size: .78rem; letter-spacing: .12em;
  color: var(--taupe);
  padding: .4em .2em;
  transition: color .3s;
}
.nav__lang:hover { color: var(--cream-dim); }
.nav__lang-opt { transition: color .35s; }
.nav__lang-opt.is-active { color: var(--gold); }
.nav__lang-sep { opacity: .5; }
.nav__burger {
  display: none;
  width: 44px; height: 44px;
  position: relative;
}
.nav__burger span {
  position: absolute; left: 10px; right: 10px; height: 1px;
  background: var(--cream);
  transition: transform .4s var(--ease-luxe), top .4s;
}
.nav__burger span:nth-child(1) { top: 18px; }
.nav__burger span:nth-child(2) { top: 26px; }
.nav__burger[aria-expanded="true"] span:nth-child(1) { top: 22px; transform: rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2) { top: 22px; transform: rotate(-45deg); }

/* ═══════════ MENU OVERLAY ═══════════ */
.menu {
  position: fixed; inset: 0; z-index: 55;
  background: linear-gradient(160deg, #120E09, var(--espresso) 70%);
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 var(--gutter);
  transform: translateY(-102%);
  visibility: hidden;
}
.menu__links { display: flex; flex-direction: column; gap: .4rem; }
.menu__link {
  display: flex; align-items: baseline; gap: 1.4rem;
  font-family: var(--serif);
  font-size: clamp(2.4rem, 9vw, 4.6rem);
  font-weight: 400;
  color: var(--cream);
  padding: .35rem 0;
  transition: color .4s, letter-spacing .6s var(--ease-out);
}
.menu__link em {
  font-family: var(--sans); font-style: normal;
  font-size: .7rem; letter-spacing: .3em; color: var(--gold);
}
.menu__link:hover { color: var(--gold-hi); letter-spacing: .02em; }
.menu__foot {
  position: absolute; bottom: 2rem; left: var(--gutter); right: var(--gutter);
  display: flex; justify-content: space-between;
  font-size: .62rem; letter-spacing: .32em; color: var(--taupe);
}

/* ═══════════ HERO ═══════════ */
.hero {
  position: relative;
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 0 var(--gutter) clamp(3.5rem, 8vh, 6rem);
  overflow: hidden;
}
.hero__media { position: absolute; inset: 0; z-index: -2; }
.hero__video {
  width: 100%; height: 100%;
  object-fit: cover;
  transform-origin: center;
}
/* The video itself carries NO filter — all hero darkening happens here, so this
   block is the only thing to touch if the footage looks too faded.
   Lightened 2026-07-21 (client: "give me more of the footage") to roughly half
   the previous top/middle darkening. PREVIOUS VALUES, for a one-line revert:
     linear-gradient(180deg, rgba(14,11,8,.62) 0%, rgba(14,11,8,.18) 38%,
                             rgba(14,11,8,.42) 68%, rgba(14,11,8,.94) 100%),
     linear-gradient(90deg,  rgba(14,11,8,.55) 0%, transparent 40%)
   Two stops are load-bearing, not aesthetic:
   · the ~.92 bottom blends the hero into the Archive (#0E0B08) — lift it and a
     hard seam appears at the section join;
   · the left ramp is what keeps the white headline/CTAs legible over bright
     frames. Don't zero either without checking both. */
.hero__veil {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 72% 12%, rgba(201,164,92,.14), transparent 46%),
    linear-gradient(180deg, rgba(14,11,8,.38) 0%, rgba(14,11,8,.06) 38%, rgba(14,11,8,.24) 68%, rgba(14,11,8,.92) 100%),
    linear-gradient(90deg, rgba(14,11,8,.42) 0%, transparent 38%);
}
.hero__stamp { margin-bottom: clamp(1.4rem, 3vh, 2.4rem); }
.hero__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3.2rem, 10.5vw, 9rem);
  line-height: .98;
  letter-spacing: .005em;
  color: var(--cream);
  text-wrap: balance;
}
body[data-lang="ja"] .hero__title { line-height: 1.18; font-size: clamp(2.6rem, 8.5vw, 7rem); }
/* padding gives descenders (g, y) room inside the reveal mask;
   negative margin cancels it so the tight leading is unchanged */
.hero__title-line { display: block; overflow: hidden; padding: .08em 0 .18em; margin: -.08em 0 -.18em; }
.hero__title-line > span { display: inline-block; }
.hero__title em {
  font-style: italic;
  background: linear-gradient(100deg, var(--gold-hi), var(--gold) 60%, var(--amber));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.hero__sub {
  margin-top: clamp(1.2rem, 2.6vh, 2rem);
  max-width: 34em;
  font-size: clamp(.85rem, 1.1vw, 1rem);
  font-weight: 300;
  letter-spacing: .06em;
  color: var(--cream-dim);
}
.hero__ctas { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: clamp(1.8rem, 4vh, 3rem); }
.hero__vertical {
  position: absolute; top: 50%; right: calc(var(--gutter) * .4);
  transform: translateY(-50%);
  writing-mode: vertical-rl;
  font-family: "Shippori Mincho", serif;
  font-size: 1.3rem; letter-spacing: .5em;
  color: rgba(201,164,92,.75);
}
.hero__scroll {
  position: absolute; bottom: 2.6rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: .8rem;
  font-size: .58rem; letter-spacing: .42em; color: var(--taupe);
}
.hero__sound {
  position: absolute; bottom: 2.6rem; right: var(--gutter);
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--sans);
  font-size: .58rem; letter-spacing: .42em; text-transform: uppercase;
  color: var(--cream-dim);
  transition: color .4s var(--ease-out);
  z-index: 4;
}
.hero__sound:hover, .hero__sound:focus-visible { color: var(--gold-hi); }
.hero__sound-eq {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 2.5px; height: 15px;
}
.hero__sound-eq i {
  display: block; width: 2px; height: 3px;
  background: currentColor;
  transition: height .3s var(--ease-out);
}
.hero__sound.is-on { color: var(--gold-hi); }
.hero__sound.is-on .hero__sound-eq i { animation: eq 1.1s ease-in-out infinite; }
.hero__sound.is-on .hero__sound-eq i:nth-child(1) { animation-delay: 0s; }
.hero__sound.is-on .hero__sound-eq i:nth-child(2) { animation-delay: .25s; }
.hero__sound.is-on .hero__sound-eq i:nth-child(3) { animation-delay: .5s; }
.hero__sound.is-on .hero__sound-eq i:nth-child(4) { animation-delay: .15s; }
@keyframes eq { 0%, 100% { height: 3px; } 50% { height: 15px; } }
.hero__scroll i {
  width: 1px; height: 54px;
  background: linear-gradient(180deg, var(--gold), transparent);
  animation: descend 2.4s var(--ease-luxe) infinite;
}
@keyframes descend {
  0% { transform: scaleY(0); transform-origin: top; }
  45% { transform: scaleY(1); transform-origin: top; }
  55% { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* ═══════════ ARCHIVE ═══════════ */
.archive {
  position: relative;
  padding: clamp(6rem, 13vh, 9rem) var(--gutter) clamp(3rem, 7vh, 5rem);
}
.archive__head { max-width: 62rem; }
.archive__title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.6rem, 5.4vw, 4.8rem);
  line-height: 1.08; color: var(--cream);
}
.archive__title span { display: block; }
.archive__title-em { font-style: italic; color: var(--gold-hi); }
.archive__intro-sub {
  font-size: .78rem; letter-spacing: .22em; color: var(--taupe);
  margin-top: 1.4rem;
}
/* live count — JS rewrites #wallCount from the DOM so it can't go stale */
.archive__count {
  display: flex; align-items: baseline; gap: .7rem;
  margin: clamp(2.6rem, 6vh, 4rem) 0 clamp(1.6rem, 3.5vh, 2.4rem);
  /* reserve the number's line box so the row height can't shift */
  min-height: clamp(2.2rem, 4vw, 3.2rem);
}
/* child combinators, not descendant — the fast-forward button's inner spans
   must not inherit the number/label styling */
.archive__count > span:first-child {
  font-family: var(--serif); font-weight: 500; font-size: clamp(2.2rem, 4vw, 3.2rem);
  color: var(--gold-hi); line-height: 1;
}
.archive__count > span:last-of-type {
  font-size: .62rem; letter-spacing: .34em; text-transform: uppercase;
  color: var(--gold);
}
/* ── SPOTLIGHT STRIPS ─────────────────────────────────── */
/* Two rows of rounded profile cards (Codrops "Creative Spotlights" reference,
   client-directed 2026-07-20): row A drifts left, row B drifts right, each
   pauses on hover. JS clones each track once for a seamless loop and adds
   .is-drifting; WITHOUT JS (or in flat / on touch) the default below is a
   native swipeable row — never overflow:hidden, or no-JS visitors would only
   ever see the first ~7 cards. */
.strips {
  display: flex; flex-direction: column;
  gap: clamp(.8rem, 1.6vh, 1.1rem);
}
.strip {
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.strip::-webkit-scrollbar { display: none; }
.strips.is-drifting .strip { overflow: hidden; }
/* soft edge fade only while the marquee runs — on the swipe fallback it would
   hide the scrollable edges */
.strips.is-drifting .strip {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.strip__track {
  display: flex;
  gap: clamp(.7rem, 1.1vw, 1rem);
  width: max-content;
  will-change: transform;
}

/* ── SCRUB BAR ────────────────────────────────────────── */
/* Two-way control under row B (client-directed 2026-07-21, replaced the
   one-directional "See all — hold" pill). Hidden unless JS runs the marquee, so
   no-JS / flat / touch never get a dead control — their rows swipe natively,
   which IS the manual control. NOT the pinned scrub retired 2026-07-20: nothing
   here pins the page. */
.strips-bar {
  display: none;
  position: relative;
  height: 18px;                 /* generous grab target… */
  margin-top: clamp(.5rem, 1.2vh, .9rem);
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.strips-bar.is-on { display: block; }
.strips-bar::before {           /* …but only a hairline is drawn */
  content: "";
  position: absolute; left: 0; right: 0; top: 50%;
  height: 2px; margin-top: -1px;
  border-radius: 999px;
  background: var(--line-dim);
}
.strips-bar__thumb {
  position: absolute; left: 0; top: 50%;
  width: 14%; height: 2px; margin-top: -1px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--amber), var(--gold) 50%, var(--gold-hi));
  will-change: transform;
  /* only transform/opacity animate; position is driven by JS translate3d */
  transition: opacity .3s var(--ease-out), box-shadow .3s var(--ease-out);
  box-shadow: 0 0 0 rgba(201,164,92,0);
}
.strips-bar:hover .strips-bar__thumb,
.strips-bar:focus-visible .strips-bar__thumb,
.strips-bar.is-scrubbing .strips-bar__thumb {
  box-shadow: 0 0 12px rgba(201,164,92,.45), 0 0 30px rgba(201,164,92,.18);
}
.strips-bar:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 4px;
  border-radius: 999px;
}
.strips-bar.is-scrubbing { cursor: grabbing; }

/* discovery cue for the scrub bar — hidden by default like the bar itself, so
   no-JS / flat / touch never see an instruction for a control they don't have */
.strips-hint {
  display: none;
  margin-top: .5rem;
  text-align: center;
  font-size: .58rem; letter-spacing: .34em; text-transform: uppercase;
  color: var(--taupe);
  transition: opacity .7s var(--ease-out);
  pointer-events: none;
}
.strips-bar.is-on ~ .strips-hint { display: block; }
.strips-hint.is-used { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .strips-hint { transition: none; } }

.atile {
  position: relative;
  flex: 0 0 auto;
  width: clamp(150px, 15vw, 205px);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: 16px;
  background: var(--coffee);
  outline: 1px solid var(--line-dim);
  outline-offset: -1px;
  display: flex; align-items: flex-end;
  transition: outline-color .4s var(--ease-out), transform .45s var(--ease-out);
}
.atile img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Colour, client-directed 2026-07-21 (replaced the long-standing B&W).
     Caveat for whoever reads this next: the mismatched-source problem the B&W
     used to hide is unresolved, not gone — 34 of the 119 files are themselves
     black-and-white (12 at zero saturation, incl. Rihanna, Skrillex, Jay-Z), so
     those tiles render mono no matter what this rule says, and backdrops still
     range from magenta to cyan. Shown the measurements, the client chose full
     colour anyway. If it ever reads as too busy, the fix is this one line:
     saturate(.5) plus a warm colorbalance pulls it into the espresso/gold
     palette and lets the mono tiles blend — that variant was built and rejected.
     The brightness dip is NOT leftover grading: it keeps names legible against
     the ::before scrim and stops 119 lit photos glaring on a near-black page. */
  filter: contrast(1.03) brightness(.88) saturate(1.02);
  transition: filter .6s var(--ease-out), transform .6s var(--ease-out);
}
/* scrim so names stay legible over any portrait */
.atile::before {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(180deg, transparent 46%, rgba(14,11,8,.8));
  pointer-events: none;
}
.atile span {
  position: relative; z-index: 3;
  padding: .7rem .75rem;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(.78rem, 1vw, .95rem);
  line-height: 1.22;
  letter-spacing: .02em;
  color: var(--cream);
  transition: color .4s var(--ease-out);
}
/* type tiles: no portrait yet — the name IS the artwork, so it has to carry
   the same visual mass as a face or it reads as a missing image */
.atile--type {
  align-items: center; justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(201,164,92,.07), transparent 70%),
    var(--chocolate);
}
/* the client's own letter-wall collage, used as the tile's "portrait".
   The source art is gold-on-white: invert+grayscale turns it into light
   letterforms on black, then screen drops the black out — no alpha asset. */
.atile--type::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: url("../assets/img/letterwall-gold.webp") center / 300px repeat;
  filter: invert(1) grayscale(1);
  mix-blend-mode: screen;
  opacity: .07;
  transition: opacity .5s var(--ease-out);
}
/* stagger the crop so no two type tiles show the same letters
   (no space before ::before — a space would target descendants) */
.atile--type:nth-child(3n)::before   { background-position: 38% 62%; }
.atile--type:nth-child(3n+1)::before { background-position: 71% 18%; }
.atile--type:nth-child(4n)::before   { background-position: 12% 84%; }
.atile--type:hover::before { opacity: .13; }
.atile--type span {
  padding: .6rem .5rem;
  text-align: center;
  text-wrap: balance;
  color: var(--cream-dim);
  font-size: clamp(.92rem, 1.25vw, 1.2rem);
  line-height: 1.16;
}
/* hover used to exist only to reveal colour; with colour now the resting state
   it lifts instead — brighter and a touch richer than base */
.atile:hover img { filter: contrast(1.02) brightness(1.06) saturate(1.08); transform: scale(1.05); }
.atile:hover span { color: var(--gold-hi); }
.atile:hover, .atile:focus-visible { outline-color: var(--line); }
.atile--type:hover { background: var(--panel); }

.archive__outro {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; gap: 2.4rem; align-items: center;
  text-align: center;
  margin-top: clamp(3.5rem, 8vh, 6rem);
}
.archive__outro-line {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(2rem, 4.4vw, 3.8rem);
  line-height: 1.15;
  color: var(--cream);
}

/* ═══════════ THE HOUSE ═══════════ */
/* Restored after the Archive (see index.html comment). Typeset, no imagery —
   this is the one purely editorial beat on the page, so it leans entirely on
   the didone and a lot of air. */
.house { padding: clamp(3.5rem, 8vh, 6rem) var(--gutter) clamp(3rem, 6.5vh, 5rem); }
.house__inner { max-width: 62rem; margin: 0 auto; text-align: center; }
/* the stamp is a flex row, so text-align alone won't move it */
.house .stamp { justify-content: center; }
.house__fact { align-items: center; }
/* the hard <br> in the body is set for desktop line balance; at narrow widths it
   fights the centring and orphans the last word, so let the text flow instead
   (text-wrap: balance on .house__body then evens the lines out) */
@media (max-width: 760px) {
  .house__body br { display: none; }
  /* Section boundaries run ~270–280px on a phone (a third of the screen) because
     both neighbours carry 16–17vh. Desktop keeps that airiness; phones get ~150px,
     matching the house→nights gap already tuned on this breakpoint. Only the
     touching edges are trimmed — each section's other side is untouched. */
  .nights  { padding-bottom: 1.75rem; }
  .reserve { padding-top: 2.25rem; padding-bottom: 1.75rem; }
  .list    { padding-top: 2.25rem; }
}
/* The space before the <br> above is deliberate: hiding a <br> does NOT insert
   whitespace, so without it the comma and the next word collide on mobile. */
.house__title {
  margin-top: clamp(2.4rem, 5vh, 3.6rem);
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.9rem);
  line-height: 1.2; color: var(--cream);
}
.house__title em { font-style: italic; color: var(--gold-hi); }
.house__body {
  margin-top: clamp(1.6rem, 3.4vh, 2.6rem);
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.35rem, 2.6vw, 2.3rem);
  line-height: 1.38; color: var(--cream);
  text-wrap: balance;
}
.house__sub {
  margin-top: clamp(1.4rem, 3vh, 2.2rem);
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  color: var(--taupe);
}
.house__facts {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.4rem, 3vw, 3rem);
  margin-top: clamp(3rem, 7vh, 5rem);
  padding-top: clamp(1.6rem, 3vh, 2.4rem);
  border-top: 1px solid var(--line-dim);
}
.house__fact { display: flex; flex-direction: column; gap: .5rem; }
.house__fact span {
  font-size: .6rem; letter-spacing: .32em; text-transform: uppercase;
  color: var(--gold);
}
.house__fact em {
  font-family: var(--serif); font-style: normal; font-weight: 400;
  font-size: clamp(.95rem, 1.3vw, 1.15rem);
  color: var(--cream-dim);
}

/* ═══════════ NIGHTS ═══════════ */
.nights { padding: clamp(5.5rem, 12vh, 9rem) var(--gutter) clamp(7rem, 16vh, 12rem); }
.nights__title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.6rem, 6vw, 5.2rem);
  margin: clamp(2.2rem, 5vh, 3.6rem) 0 clamp(3rem, 7vh, 5rem);
}
.nights__title em { font-style: italic; color: var(--gold-hi); }
.nights__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.6rem, 3vw, 3rem);
  /* stretch + equal rows so short cards (Fri/Sat/Sun, day + time only) match the
     tall ones (Tue/Beyakeo, which carry a name + note) — client-directed. */
  align-items: stretch;
  grid-auto-rows: 1fr;
}
/* Cards are typeset, not flyer images (client-directed 2026-07-21): the six real
   flyers share no visual language — dark green, blue-grey, neon magenta — so as
   card art they read as unrelated posters and none match the espresso palette.
   Setting them in the site's own type keeps the section coherent, legible at card
   size, bilingual, and free of the dates that made the old cards expire. */
.ncard {
  display: block; position: relative;
  padding: clamp(1.6rem, 2.4vw, 2.4rem) clamp(1.4rem, 2vw, 2rem) clamp(1.3rem, 2vw, 1.9rem);
  border-radius: 18px;
  background:
    radial-gradient(120% 80% at 12% 0%, rgba(201,164,92,.10), transparent 58%),
    linear-gradient(165deg, var(--chocolate) 0%, var(--coffee) 100%);
  outline: 1px solid var(--line-dim); outline-offset: -1px;
  overflow: hidden;
  transition: transform .5s var(--ease-out), outline-color .5s var(--ease-out);
}
/* Flyer background per card (client-directed 2026-07-21). The real recurring
   flyers, blurred + darkened so each night has its own atmosphere without the
   clashing neon/green/blue palettes fighting the espresso design — the reason the
   cards were typeset in the first place. Warm grade is baked into the WebP; blur
   and dim are CSS so hover can ease the flyer into focus. Sits below the text. */
.ncard__flyer {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center;
  transform: scale(1.18);                 /* hides the blur's soft edges */
  filter: blur(12px) brightness(.42) saturate(.85);
  transition: filter .6s var(--ease-out), transform .6s var(--ease-out);
  pointer-events: none;
}
.ncard__flyer::after {                     /* scrim: keeps gold/cream text legible */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(165deg, rgba(20,16,12,.5) 0%, rgba(14,11,8,.8) 100%);
}
.ncard:hover .ncard__flyer,
.ncard:focus-visible .ncard__flyer {
  filter: blur(6px) brightness(.64) saturate(1);
  transform: scale(1.08);
}
/* Touch devices can't hover, so pin the flyer to its brighter/sharper state —
   otherwise mobile only ever sees the dim resting blur. */
@media (hover: none) {
  .ncard__flyer { filter: blur(6px) brightness(.64) saturate(1); transform: scale(1.08); }
}
/* text + hairline ride above the flyer */
.ncard > :not(.ncard__flyer) { position: relative; z-index: 1; }

.ncard::after {          /* hairline that draws in on hover */
  content: ""; position: absolute; inset: 10px; z-index: 2;
  border: 1px solid rgba(201,164,92,0); border-radius: 12px;
  transition: border-color .55s var(--ease-out);
  pointer-events: none;
}
.ncard-pair { display: contents; }  /* transparent to the grid; only the slider re-groups it */
/* Zigzag stagger retired 2026-07-31 (client-directed) — the offset made a
   dynamically-rebuilt roster read as misaligned rather than deliberate, most
   visibly on BEYAKEO. .ncard--offset is kept as a no-op (rather than removed
   from the markup/JS) in case a future design revisits it. */
.ncard--offset { transform: none; }
.ncard:hover, .ncard:focus-visible { outline-color: var(--line); }
.ncard:hover::after, .ncard:focus-visible::after { border-color: var(--line-dim); }
.ncard:hover { transform: translateY(-4px); }

.ncard__day {
  display: block;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.9rem, 3vw, 2.9rem); line-height: 1;
  color: var(--cream);
  transition: color .4s var(--ease-out);
}
.ncard:hover .ncard__day { color: var(--gold-hi); }
.ncard__name {
  margin: .85rem 0 0;
  font-family: var(--sans); font-weight: 400;
  font-size: clamp(.68rem, .9vw, .78rem);
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--gold);
  line-height: 1.5;
}
.ncard__meta {
  display: flex; align-items: baseline; gap: .8rem;
  margin-top: 1.5rem;
  font-size: .64rem; letter-spacing: .28em; text-transform: uppercase;
  color: var(--cream-dim);
}
.ncard__floor {
  padding: .25em .6em;
  border: 1px solid var(--line-dim); border-radius: 999px;
  color: var(--gold);
}
.ncard__note {
  margin-top: .55rem;
  font-size: .62rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--taupe);
}
.ncard__go {
  display: inline-block; margin-top: 1.4rem;
  font-size: .62rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold);
  transition: color .4s var(--ease-out), transform .4s var(--ease-out);
}
.ncard:hover .ncard__go { color: var(--gold-hi); transform: translateX(4px); }


/* ═══════════ SPECIAL ANNOUNCEMENT ═══════════
   One-off pop-up artist / guest performance. Markup is injected by the
   `announce` module in js/main.js from a single ANNOUNCEMENT config object.

   Ratio-agnostic by design: every flyer uses width:100% + height:auto inside a
   max-width cap, so 3:4 (the design target), 4:5, or anything else renders
   UNCROPPED. Never add object-fit/aspect-ratio here — the whole point is that
   marketing never has to match a pixel spec.
   ═══════════════════════════════════════════════ */

/* ── featured block — sits ABOVE the six recurring night cards ──
   Its own block rather than a 7th .ncard: those render typeset text over a
   blurred flyer, which would collide with the flyer's own baked-in text. The
   18px radius + hairline outline are borrowed from .ncard so it still reads as
   part of the same family while being structurally separate. */
.sfeat {
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(1.1rem, 2vw, 1.6rem);
  margin: 0 auto clamp(3.5rem, 7vw, 5.5rem);
  text-align: center;
}
.sfeat__label {
  font-size: .68rem; letter-spacing: .34em; text-transform: uppercase;
  color: var(--gold);
}
.sfeat__frame {
  display: block;
  width: min(100%, 420px);
  border-radius: 18px; overflow: hidden;
  outline: 1px solid var(--line); outline-offset: -1px;
  box-shadow:
    0 1px 2px rgba(0,0,0,.35),
    0 18px 48px rgba(10,6,2,.5),
    0 40px 90px rgba(201,164,92,.06);
  transition: transform .5s var(--ease-out), outline-color .5s var(--ease-out);
}
.sfeat__frame:hover { transform: translateY(-4px); outline-color: var(--gold); }
.sfeat__frame:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.sfeat__flyer { display: block; width: 100%; height: auto; }

/* ── entry pop-up ──
   z-index 95: above the nav (60) and the film grain (90) so the flyer stays
   crisp and legible, but below the preloader (100) and cursor (110). */
.sapop { position: fixed; inset: 0; z-index: 95; pointer-events: none; }
.sapop[hidden] { display: none; }
.sapop__backdrop { display: none; }
.sapop__panel {
  position: absolute;
  right: clamp(1.1rem, 2.4vw, 2.2rem);
  bottom: clamp(1.1rem, 2.4vw, 2.2rem);
  width: clamp(300px, 24vw, 380px);
  pointer-events: auto;
  border-radius: 18px; overflow: hidden;
  background: linear-gradient(165deg, var(--chocolate) 0%, var(--coffee) 100%);
  outline: 1px solid var(--line); outline-offset: -1px;
  box-shadow:
    0 2px 6px rgba(0,0,0,.4),
    0 24px 60px rgba(10,6,2,.6),
    0 50px 110px rgba(201,164,92,.07);
}
.sapop__frame { display: block; }
.sapop__flyer { display: block; width: 100%; height: auto; }
.sapop__cta {
  display: block; width: 100%; text-align: center;
  border: 0; border-top: 1px solid var(--line-dim);
  border-radius: 0;
}
.sapop__close {
  position: absolute; top: .6rem; right: .6rem; z-index: 2;
  width: 2.2rem; height: 2.2rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(14,11,8,.62);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--cream); font-size: 1.35rem; line-height: 1;
  transition: background-color .3s var(--ease-out), color .3s var(--ease-out),
              transform .2s var(--ease-out);
}
.sapop__close:hover { background: rgba(14,11,8,.88); color: var(--gold-hi); transform: scale(1.07); }
.sapop__close:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Mobile: becomes a genuine centred modal with a dimming backdrop.
   Centred with flex rather than translate(-50%,-50%) ON PURPOSE — GSAP animates
   the panel's y/scale on entry, and a transform-based centring would be
   overwritten by it. */
@media (max-width: 768px) {
  .sapop { display: flex; align-items: center; justify-content: center; padding: 1.2rem; }
  .sapop__backdrop {
    display: block; position: absolute; inset: 0;
    /* .52 not .74 (2026-07-29, client-directed): at .74 the page behind read as
       almost black. Still enough separation to focus the flyer, but the site
       stays visible underneath. Blur eased to 2px for the same reason. */
    background: rgba(6,4,2,.52);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
    pointer-events: auto;
  }
  .sapop__panel {
    position: relative; right: auto; bottom: auto;
    width: min(86vw, 380px);
    max-height: calc(100vh - 2.4rem);
    overflow-y: auto;
  }
}

/* ── re-open tab — only ever shown AFTER a dismissal ── */
.satab {
  position: fixed; z-index: 94;
  right: 0; top: 50%; transform: translateY(-50%);
  padding: 1.15rem .6rem;
  writing-mode: vertical-rl;
  font-family: var(--sans);
  font-size: .6rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold-hi);
  background: linear-gradient(165deg, var(--chocolate) 0%, var(--coffee) 100%);
  border: 1px solid var(--line); border-right: 0;
  border-radius: 10px 0 0 10px;
  box-shadow: -6px 0 24px rgba(10,6,2,.45);
  transition: color .3s var(--ease-out), transform .35s var(--ease-out);
}
.satab[hidden] { display: none; }
/* keep the -50% or the tab jumps out of vertical centre on hover */
.satab:hover { color: var(--cream); transform: translateY(-50%) translateX(-3px); }
.satab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }


/* ═══════════ RESERVE ═══════════ */
.reserve { position: relative; padding: clamp(7rem, 16vh, 12rem) var(--gutter); overflow: hidden; }
.reserve__bg {
  position: absolute; inset: 0; z-index: -2;
  background: url("../assets/img/bar-macro.webp") center / cover no-repeat;
  opacity: .16;
}
.reserve::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, var(--ambient) 0%, rgba(24,17,9,.55) 45%, var(--ambient) 100%);
}
.reserve__map {
  position: absolute; right: -6%; top: 8%;
  width: min(58vw, 900px); aspect-ratio: 1400 / 1049;
  background: url("../assets/img/venue-map-gold.webp") center / contain no-repeat;
  opacity: .09;
  z-index: -1;
  pointer-events: none;
}
.reserve__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(3rem, 7vw, 7rem);
  align-items: center;
  max-width: 76rem;
  margin: 0 auto;
}
.reserve__title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.8rem, 5.6vw, 5rem);
  line-height: 1.04;
  margin: clamp(2rem, 4.5vh, 3.2rem) 0 1.6rem;
}
.reserve__title em { font-style: italic; color: var(--gold-hi); }
.reserve__sub { color: var(--cream-dim); max-width: 30em; letter-spacing: .04em; }
/* Scope notice (2026-07-31): guests were using this form to ask about guest list /
   general entry. A gold left-rule rather than a boxed "alert" — a warning box would
   fight the section's luxury tone, but the rule still reads as a distinct aside. */
.reserve__only {
  margin: 1.4rem 0 0;
  padding: .2rem 0 .2rem 1.1rem;
  border-left: 2px solid var(--gold);
  font-size: .84rem; line-height: 1.7;
  color: var(--cream-dim);
  max-width: 34ch;
}
.reserve__note {
  margin-top: 2.2rem;
  font-size: .64rem; letter-spacing: .34em; color: var(--gold);
}

.rform {
  position: relative;
  padding: clamp(1.8rem, 3.5vw, 3rem);
  background: linear-gradient(150deg, rgba(34,26,18,.72), rgba(20,16,12,.66));
  border: 1px solid var(--line-dim);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow:
    0 1px 2px rgba(0,0,0,.35),
    0 12px 32px rgba(10,6,2,.45),
    0 32px 80px rgba(201,164,92,.05);
}
.rform__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
.rform__row--tight { gap: 1rem; grid-template-columns: 1.2fr 1fr .8fr; }
.rform__field { display: flex; flex-direction: column; gap: .45rem; margin-bottom: 1.5rem; min-width: 0; }
.rform__field--s { flex: 0 0 auto; }
.rform label {
  font-size: .6rem; letter-spacing: .32em; text-transform: uppercase;
  color: var(--taupe);
  transition: color .35s;
}
.rform input, .rform select, .rform textarea {
  background: transparent;
  border: 0; border-bottom: 1px solid var(--line-dim);
  color: var(--cream);
  font-family: var(--sans); font-weight: 300;
  font-size: .95rem;
  letter-spacing: .04em;
  padding: .45em 0 .6em;
  border-radius: 0;
  transition: border-color .4s;
  color-scheme: dark;
  width: 100%;
}
.rform textarea { resize: vertical; min-height: 2.6em; }
.rform input::placeholder, .rform textarea::placeholder { color: rgba(185,172,151,.4); }
.rform input:focus, .rform select:focus, .rform textarea:focus {
  outline: none;
  border-bottom-color: var(--gold);
}
.rform__field:focus-within label { color: var(--gold); }
.rform__phone { width: 100%; }

/* intl-tel-input (phone widget, lazy-loaded — js/main.js) themed to match the
   form's dark, hairline-bordered look instead of the library's default light
   boxed style. Shared by .rform__phone and .lform__phone; the underlying
   <input> keeps its normal `.rform input`/`.lform input` styling untouched.
   Class names verified against the actual rendered DOM (v23.8.0) via a headless
   browser check — this library's structure doesn't match its older docs
   (`.iti__selected-country`, not `.iti__selected-flag`; `.iti__country-container`,
   not `.iti__flag-container`). The library computes the input's left padding
   itself via inline style to match the flag button's real width — don't
   override that, it'll fall out of sync with the button on font/zoom changes. */
.iti { width: 100%; }
.iti__selected-country {
  background: transparent;
  border-radius: 0;
}
.iti__selected-country:hover, .iti__selected-country:focus {
  background: rgba(201,164,92,.1);
}
.iti__selected-dial-code { color: var(--cream-dim); font-size: .92rem; }
.iti__arrow { border-top-color: var(--taupe); }

/* !important here: the library's own CSS (loaded after main.css, and using
   selectors of equal-or-higher specificity for its dropdown panel) otherwise
   wins the cascade over these single-class overrides — verified by testing
   without !important first, where these silently fell back to the library's
   white default. Legitimate for reskinning a third-party widget whose internal
   selector specificity isn't something we control. */
.iti__dropdown-content, .iti__country-list {
  background: var(--chocolate) !important;
  border: 1px solid var(--line) !important;
  border-radius: 4px;
  box-shadow: 0 12px 32px rgba(10,6,2,.5);
}
.iti__country { color: var(--cream-dim) !important; font-size: .85rem; }
.iti__country.iti__highlight, .iti__country:hover {
  background: rgba(201,164,92,.12) !important;
  color: var(--cream) !important;
}
.iti__country-name { color: inherit; }
.iti__dial-code { color: var(--taupe) !important; }
.iti__divider { border-bottom: 1px solid var(--line-dim); }
.iti__search-input {
  background: var(--coffee) !important;
  border: 1px solid var(--line-dim) !important;
  color: var(--cream) !important;
  font-family: var(--sans);
  border-radius: 3px;
}
.iti__search-input:focus { outline: none; border-color: var(--gold) !important; }
.iti__search-input::placeholder { color: rgba(185,172,151,.4); }

/* "reachable on" — WhatsApp / LINE */
.rform__reach { border: 0; margin-top: .9rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem; }
.rform__reach legend {
  float: left; width: 100%; margin-bottom: .5rem;
  font-size: .6rem; letter-spacing: .28em; text-transform: uppercase; color: var(--cream-dim);
}
.rform__check {
  display: inline-flex; align-items: center; gap: .55rem;
  font-size: .78rem; letter-spacing: .06em; color: var(--cream-dim);
  cursor: pointer; transition: color .3s var(--ease-out);
}
.rform__check:hover { color: var(--cream); }
.rform__check input {
  appearance: none; -webkit-appearance: none;
  width: 1.05rem; height: 1.05rem; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: 3px;
  background: rgba(255,255,255,.02);
  display: grid; place-content: center;
  transition: border-color .3s var(--ease-out), background-color .3s var(--ease-out);
}
.rform__check input::after {
  content: ""; width: .5rem; height: .5rem; border-radius: 1px;
  background: var(--gold-hi); transform: scale(0);
  transition: transform .2s var(--ease-out);
}
.rform__check input:checked { border-color: var(--gold); }
.rform__check input:checked::after { transform: scale(1); }
.rform__lineid { margin-top: 1rem; margin-bottom: 0; }
/* `.rform__field` sets display:flex, which beats the [hidden] attribute's
   display:none — without this the LINE ID field shows even when LINE is unticked */
.rform__lineid[hidden] { display: none; }

/* required-field note — shared by .rform and .lform (2026-07-28) */
.rform__reqnote {
  font-size: .72rem; letter-spacing: .02em;
  color: var(--cream-dim);
  margin: 0 0 1.4rem;
}

/* phone-conditional SMS consent, .lform only (2026-07-28) — a plain block with no
   explicit display rule, so [hidden] just works with no override needed. */
.lform__smsconsent { margin: 1rem 0 0; }
.lform__smsconsent .rform__check {
  align-items: flex-start; gap: .7rem;
  font-size: .74rem; line-height: 1.5; color: var(--cream-dim);
}
.lform__smsconsent .rform__check input { margin-top: .15rem; }

/* consent — required, so it reads as part of the commitment not fine print */
.rform__consent {
  align-items: flex-start; gap: .7rem;
  margin: .4rem 0 1.4rem;
  font-size: .74rem; line-height: 1.5; color: var(--cream-dim);
}
.rform__consent input { margin-top: .15rem; }

/* honeypot — visually gone, still reachable by bots */
.rform__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.rform__submit { width: 100%; margin-top: .6rem; }
.rform__done {
  margin-top: 1.4rem;
  font-family: var(--serif); font-style: italic;
  font-size: 1.06rem; color: var(--gold-hi);
  text-align: center;
}

/* ═══════════ LIST ═══════════ */
.list {
  position: relative;
  padding: clamp(7rem, 17vh, 13rem) var(--gutter);
  text-align: center;
  overflow: hidden;
}
.list__texture {
  position: absolute; inset: -30%;
  background: url("../assets/img/letterwall-gold.webp") center / 1100px repeat;
  opacity: .016;
  transform: rotate(3deg);
  pointer-events: none;
  -webkit-mask-image: radial-gradient(60% 60% at 50% 42%, #000, transparent 75%);
  mask-image: radial-gradient(60% 60% at 50% 42%, #000, transparent 75%);
}
.list .stamp { justify-content: center; }
.list__script {
  width: min(420px, 74vw); height: auto;
  margin: clamp(2.5rem, 6vh, 4rem) auto 0;
  filter: drop-shadow(0 0 18px rgba(224,60,60,.35)) drop-shadow(0 0 60px rgba(224,60,60,.18));
  animation: neon 5s ease-in-out infinite;
}
@keyframes neon {
  0%, 100% { filter: drop-shadow(0 0 18px rgba(224,60,60,.35)) drop-shadow(0 0 60px rgba(224,60,60,.18)); opacity: 1; }
  50%      { filter: drop-shadow(0 0 26px rgba(224,60,60,.5))  drop-shadow(0 0 80px rgba(224,60,60,.26)); opacity: .93; }
}
.list__line {
  margin-top: clamp(2rem, 5vh, 3.4rem);
  font-family: var(--serif);
  font-size: clamp(1.2rem, 2.2vw, 1.7rem);
  color: var(--cream-dim);
}
.list__line em { font-style: italic; color: var(--gold-hi); }
/* Signup grew from a single email field to name + email + phone (client-directed
   2026-07-21). Kept the section's minimal underline styling rather than borrowing
   the boxed reserve-form look, so it still reads as a quiet sign-up and not a
   second reservation form. */
.lform {
  width: min(520px, 88vw);
  margin: 2.6rem auto 0;
  text-align: left;
}
.lform__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.lform__field { display: flex; flex-direction: column; gap: .4rem; margin-bottom: 1.2rem; min-width: 0; }
.lform__field > label {          /* NOT `.lform label` — that also hit the consent
                                    label and rendered it as tiny uppercase caps */
  font-size: .58rem; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cream-dim);
  transition: color .3s var(--ease-out);
}
.lform__field:focus-within label { color: var(--gold); }
.lform input:not([type="checkbox"]), .lform select {
  /* the :not() matters — without it this also hit the consent checkbox, giving it
     width:100% and an underline, which squeezed the label text into a sliver */
  width: 100%;
  background: transparent; border: 0; outline: none;
  border-bottom: 1px solid var(--line);
  color: var(--cream);
  font-family: var(--sans); font-weight: 300;
  font-size: .92rem; letter-spacing: .04em;
  padding: .55em .1em;
  transition: border-color .4s var(--ease-out);
}
.lform select { appearance: none; -webkit-appearance: none; cursor: pointer; }
.lform option { background: var(--chocolate); color: var(--cream); }
.lform input:not([type="checkbox"]):focus, .lform select:focus { border-bottom-color: var(--gold); }
.lform__phone { width: 100%; }
.lform__consent {
  display: flex; width: 100%;    /* .rform__check is inline-flex, which collapsed
                                    this to a narrow column beside the phone row */
  align-items: flex-start; gap: .7rem;
  margin: .2rem 0 1.5rem;
  font-size: .72rem; line-height: 1.5; letter-spacing: normal; text-transform: none;
  color: var(--cream-dim);
  text-align: left;
}
.lform__consent input { margin-top: .15rem; }
.lform__submit { width: 100%; }
@media (max-width: 520px) {
  .lform__row { grid-template-columns: 1fr; gap: 0; }
}
.lform__done {
  margin-top: 1.6rem;
  font-family: var(--serif); font-style: italic;
  color: var(--gold-hi);
}

/* ═══════════ FOOTER ═══════════ */
.foot {
  position: relative;
  padding: clamp(6rem, 14vh, 10rem) var(--gutter) 2.4rem;
  overflow: hidden;
  border-top: 1px solid var(--line-dim);
}
.foot__dawn {
  position: absolute; inset: 0 0 auto 0; height: 60%;
  background:
    radial-gradient(90% 70% at 78% 0%, rgba(200,120,50,.14), transparent 55%),
    radial-gradient(60% 50% at 20% 0%, rgba(201,164,92,.08), transparent 60%);
  pointer-events: none;
}
.foot__sign {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.8rem, 7.5vw, 6.4rem);
  line-height: 1.04;
  margin: clamp(2.4rem, 6vh, 4rem) 0 clamp(3rem, 8vh, 5.5rem);
}
.foot__sign em { font-style: italic; color: var(--gold-hi); }
/* Tracks hug their content and the free space is split evenly between them
   (2026-07-31, client-directed). Was repeat(4, minmax(0,1fr)) + max-width:68rem,
   which pinned all four columns into the left ~70% of the footer: the last
   column's text ended at x≈999 while .foot__base's divider below it spans the
   full width to x≈1536 — a dead third on the right. Equal 1fr tracks also made
   the FOLLOW→HOURS gap read as double the others, since "Instagram" is ~59px
   against ~175px for the address/email. NO max-width on purpose — capping the
   columns under a full-width divider is exactly what caused this. */
.foot__cols {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, auto);
  justify-content: space-between;
  gap: 2rem;                 /* now the MINIMUM gap; space-between adds the rest */
  padding-bottom: clamp(3rem, 7vh, 5rem);
}
.foot__col h3 {
  font-size: .6rem; font-weight: 400; letter-spacing: .34em; text-transform: uppercase;
  color: var(--gold);
  margin-bottom: .9rem;
}
.foot__col p { font-size: .85rem; line-height: 1.9; color: var(--cream-dim); letter-spacing: .04em; }
.foot__col .foot__entry {
  margin-top: .5rem;
  font-size: .62rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  /* cream-dim, not taupe: this line sits over the lit Tokyo Tower art,
     and it's an access policy guests actually need to read */
  color: var(--cream-dim);
}
.foot__col a { position: relative; transition: color .35s; }
.foot__col a:hover { color: var(--gold-hi); }
.foot__base {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 1.6rem;
  /* was space-between when a third item (the Reserve link) sat on the right —
     with two children that would strand the crest and the © line at the edges */
  justify-content: flex-start;
  border-top: 1px solid var(--line-dim);
  padding-top: 1.6rem;
  font-size: .68rem; letter-spacing: .22em; color: var(--taupe);
}
.foot__crest { height: 54px; width: auto; opacity: .85; }

/* ═══════════ JAPANESE TYPOGRAPHY ═══════════ */
/* Japanese was illegibly small site-wide. Three compounding causes, all of which
   are Latin-first defaults rather than individual mistakes:
     1. sizes of .58–.72rem (9–11.5px) — fine for Latin caps, a smudge for kanji,
        which fill the whole em box with far more strokes;
     2. letter-spacing .2–.42em — a Latin-uppercase convention that makes
        先 行 案 内 read as four characters instead of one word;
     3. body { font-weight: 300 } — at 9px, weight-300 Japanese is barely ink.
   Fixed here as ONE block scoped to the language, extending the existing
   `body[data-lang="ja"] .hero__title` precedent. Client chose ~+30% and tighter
   tracking (tried +40% first, dialled back). LATIN IS UNTOUCHED — nothing below applies unless data-lang="ja".
   If a component overflows at these sizes, fix that component's gap/breakpoint;
   do NOT shrink the tiers, the text needs to be this size to be readable. */
body[data-lang="ja"] { font-weight: 400; }

/* tier 1 — was .58rem */
body[data-lang="ja"] .hero__scroll,
body[data-lang="ja"] .hero__sound,
body[data-lang="ja"] .strips-hint,
body[data-lang="ja"] .lform__field > label { font-size: .76rem; letter-spacing: .14em; }

/* tier 2 — was .60–.62rem */
body[data-lang="ja"] .foot__col h3,
body[data-lang="ja"] .house__fact span,
body[data-lang="ja"] .rform label,
body[data-lang="ja"] .rform__reach legend,
body[data-lang="ja"] .archive__count > span:last-of-type,
body[data-lang="ja"] .menu__foot,
body[data-lang="ja"] .ncard__go,
body[data-lang="ja"] .satab,
body[data-lang="ja"] .ncard__note { font-size: .80rem; letter-spacing: .14em; }

/* tier 3 — was .64–.68rem */
/* .nav__lang removed 2026-07-27 — it's now a fixed size in both languages,
   set directly on the base .nav__lang rule instead of here. */
body[data-lang="ja"] .stamp,
body[data-lang="ja"] .ncard__meta,
body[data-lang="ja"] .reserve__note,
body[data-lang="ja"] .foot__base,
body[data-lang="ja"] .sfeat__label,
body[data-lang="ja"] .ncard__name { font-size: .88rem; letter-spacing: .14em; }

/* tier 4 — was .70–.72rem */
body[data-lang="ja"] .nav__link,
body[data-lang="ja"] .menu__link em,
body[data-lang="ja"] .btn,
body[data-lang="ja"] .rform__reqnote { font-size: .92rem; letter-spacing: .14em; }

/* .nav__cta (top-right "Reserve"/"ご予約" button) — 2026-07-27: EN reverted to
   its ORIGINAL size (falls through to base .btn's .72rem, no override needed).
   JA stays fixed at .82rem, the EN/JA midpoint from the previous pass, per
   explicit instruction to only revert English. This reintroduces a visible
   size difference between languages at this one spot — that's the ask, not
   a bug. font-size ONLY: letter-spacing is intentionally left alone, so JA
   still gets the tier-4 .14em tracking fix (wide Latin-caps spacing reads
   ご予約 as separate characters). Same specificity as the .btn rules above
   (0,0,2,0), so placement AFTER them is what wins the cascade tie; don't
   move this block earlier in the file. */
body[data-lang="ja"] .nav__cta { font-size: .82rem; }

/* tier 5 — was .78–.85rem */
body[data-lang="ja"] .archive__intro-sub,
body[data-lang="ja"] .rform__check,
body[data-lang="ja"] .lform__consent,
body[data-lang="ja"] .foot__col p,
body[data-lang="ja"] .hero__sub { font-size: 1rem; letter-spacing: .1em; }

/* These set font-weight:300 explicitly, so they ignore the body-level override
   above — what the user types into a form is Japanese too, and 300 is too light. */
body[data-lang="ja"] .hero__sub,
body[data-lang="ja"] .rform input,
body[data-lang="ja"] .rform select,
body[data-lang="ja"] .rform textarea,
body[data-lang="ja"] .lform input:not([type="checkbox"]),
body[data-lang="ja"] .lform select { font-weight: 400; }

/* Japanese nav labels are wider than their Latin equivalents, and at .98rem the
   five of them + toggle + CTA wrap onto two lines below ~1080px. Rather than
   shrinking the text back down, Japanese collapses to the burger earlier — the
   fullscreen menu already carries all six destinations with their timestamps.
   English keeps its 900px breakpoint. */
@media (max-width: 1080px) {
  body[data-lang="ja"] .nav__links,
  body[data-lang="ja"] .nav__cta { display: none; }
  body[data-lang="ja"] .nav__burger { display: block; }
}

/* excluded on purpose: .atile span (artist names are Latin in both languages),
   .stamp__time (digits), and the large serif headings (already 22px+). */

/* ═══════════ REVEAL STATES (JS sets .is-in) ═══════════ */
.reveal-line .stamp__rule { transform: scaleX(0); transition: transform 1.1s var(--ease-luxe) .15s; }
.reveal-line.is-in .stamp__rule { transform: scaleX(1); }

/* ═══════════ RESPONSIVE ═══════════ */
/* Five nav links + language toggle + CTA is a lot of bar. Between the burger
   breakpoint (900px) and ~1100px the labels wrapped to two lines — tighten the
   gap and letterspacing rather than cramming or collapsing early. */
@media (max-width: 1100px) {
  .nav__links { gap: 1.5rem; }
  .nav__link { letter-spacing: .18em; }
  .nav { gap: 1.2rem; }
}

@media (max-width: 1080px) {
  .nights__grid { grid-template-columns: repeat(2, 1fr); }
  .ncard--offset { transform: none; }
  .reserve__grid { grid-template-columns: 1fr; }
  .reserve__map { opacity: .045; width: 90vw; right: -20%; }
}
@media (max-width: 900px) {
  .nav__links, .nav__cta { display: none; }
  .nav__burger { display: block; }
  .hero__vertical { display: none; }
  /* touch: no marquee (JS skips it) — the default .strip swipe takes over.
     Slightly smaller cards so ~2.4 are visible at 390px. */
  .atile { width: clamp(132px, 38vw, 170px); }
  /* Back to equal 1fr tracks below 900px: the content-sized tracks above need
     ~604px (content + minimum gaps), which gets tight in the 641–900px band.
     Reproduces the pre-2026-07-31 rendering exactly — the old max-width:68rem
     never bound down here anyway (available width is already < 1088px). */
  .foot__cols { grid-template-columns: repeat(4, minmax(0, 1fr)); justify-content: stretch; }
}
@media (max-width: 640px) {
  .nav { gap: .9rem; padding-left: 1.1rem; padding-right: .8rem; }
  .nav__right { gap: .7rem; }
  .nav__logo img { height: 30px; }
  .hero__ctas { flex-direction: column; align-items: stretch; max-width: 22rem; }
  .btn { text-align: center; }
  .hero__scroll { display: none; }
  .stamp { letter-spacing: .26em; gap: .8rem; }
  /* Nights→Reserve gap was too large on mobile — .nights' bottom padding and
     .reserve's top padding (both clamp(7rem,16vh,12rem) on desktop) combined
     to 224–288px of dead space between the last card and the Reserve heading.
     Longhand overrides so only the touching sides shrink — .nights' top
     padding (spacing after The House above it) and .reserve's bottom padding
     (spacing before List below it) are untouched. */
  .nights { padding-bottom: clamp(2.5rem, 6vh, 4rem); }
  /* Same fix, Reserve→List boundary: .reserve's bottom padding and .list's
     top padding (clamp(7rem,16vh,12rem) / clamp(7rem,17vh,13rem) on desktop)
     had the same dead-space problem. .list's bottom padding (spacing before
     the Footer below it) is untouched. */
  .reserve { padding-top: clamp(2.5rem, 6vh, 4rem); padding-bottom: clamp(2.5rem, 6vh, 4rem); }
  .list { padding-top: clamp(2.5rem, 6vh, 4rem); }
  /* Nights becomes a horizontal swipe slider on phones — the vertical stack of
     six cards was too long. Native CSS scroll-snap: one card per swipe, neighbours
     peek at the edges to signal it's swipeable. Saturday's two cards ride together
     in one slide (.ncard-pair). No JS. */
  .nights__grid {
    display: flex;
    grid-template-columns: none;
    align-items: flex-start;   /* each card sizes to its own content */
    gap: 1rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    /* pull to the screen edges so cards can sit ~82vw with neighbours peeking */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    padding-bottom: .5rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .nights__grid::-webkit-scrollbar { display: none; }
  .nights__grid > .ncard,
  .nights__grid > .ncard-pair {
    flex: 0 0 82vw;
    scroll-snap-align: center;
    min-width: 0;
  }
  /* The Saturday slide holds two stacked cards (220px + 16px gap + 220px = 456px).
     The single-card slides (Tue/Thu/Fri/Sun) would otherwise be 190–220px, so
     swiping to Saturday visibly grows the slider. Match them to the pair's
     combined height so every slide is the same size. Direct-child selector only
     — doesn't touch the two cards INSIDE the pair, which stay 220px each. */
  .nights__grid > .ncard { min-height: 456px; }
  /* Tuesday: desktop uses the landscape 3:2 crop (inline style in the HTML);
     mobile swaps to the original portrait flyer. Class rule + no !important —
     this loads after the inline… wait, inline always wins on the SAME property,
     so the class alone can't override it. Beating an inline style requires either
     !important or removing the inline style; !important is simplest here since
     it's one property on one element, not a pattern to maintain. */
  .ncard__flyer--tue { background-image: url("../assets/img/flyers/tuesday-mobile.webp") !important; }
  /* CMS-rendered cards (2026-07-31): generalizes the Tuesday trick above so
     ANY night can carry an optional mobile-specific crop from Airtable,
     without a dedicated CSS rule per night. js/main.js always sets the
     --flyer-mobile custom property on CMS cards — to the dedicated mobile
     crop if marketing uploaded one, else to the same desktop image — so
     this rule always resolves to a valid url() for them. The six hardcoded
     fallback cards never set --flyer-mobile, so var() is invalid there and
     this declaration is simply skipped, leaving their existing inline image
     (and .ncard__flyer--tue above) in charge exactly as before. */
  .ncard__flyer { background-image: var(--flyer-mobile) !important; }
  /* Saturday pair: the two cards stack inside their single slide */
  .ncard-pair { display: flex; flex-direction: column; gap: 1rem; }
  .ncard-pair > .ncard { flex: 1 1 auto; }
  .ncard--offset { transform: none; }   /* no stagger inside the slider */
  /* B1 Saturday has no name line, so at natural height it's shorter than every
     other card in the slider (measured 220px elsewhere, this one ~190px) —
     match it to Beyakeo so the pair reads as one consistent unit. Mobile only. */
  .ncard-pair > .ncard:first-child { min-height: 220px; }

  /* First/Last stay side-by-side on mobile too (client-directed 2026-07-31) —
     previously collapsed to one column here; .rform__row--tight below already
     fully overrides its own grid-template-columns regardless, so removing this
     doesn't affect the Date/Arrival/Guests row. */
  .rform__row--tight { grid-template-columns: 1.3fr 1fr; gap: 1rem; }
  /* Email/Phone were briefly paired side-by-side on mobile (2026-07-31) but
     reverted the same day — felt too tight, back to full-width/stacked. */
  .foot__cols { grid-template-columns: repeat(2, 1fr); }
  .foot__base { flex-wrap: wrap; row-gap: 1rem; }
}

/* ═══════════ FLAT MODE (?flat=1 · reduced motion · no-JS) ═══════════ */
body.flat .preloader { display: none; }
body.flat .cursor { display: none; }
body.flat [data-anim] { opacity: 1 !important; transform: none !important; }
body.flat .reveal-line .stamp__rule { transform: scaleX(1); }
/* flat: the strips' default state is already the right fallback (native
   swipe, no clones, no drift) — belt-and-braces kill any leftover transform */
body.flat .strip__track { transform: none !important; }

/* ═══════════ REDUCED MOTION ═══════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body::after { animation: none; }
  .hero__scroll i { animation: none; }
  .list__script { animation: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
}

@media (max-width: 900px) {
  /* Mobile-only reorder within the swipeable fallback rows (client-directed
     2026-07-25): Travis Scott ahead of Future in row A, Justin Bieber ahead
     of Rihanna in row B. Pure visual reorder via nth-child + order — HTML/DOM
     stays untouched, so desktop's JS marquee (querySelectorAll DOM order,
     tile cloning, row-B fame reversal) is unaffected; the 900px query keeps
     desktop from ever seeing this. CSS default order is 0 for every flex item,
     so ALL tiles in a row need an explicit value — assigning order only to
     the two swapped tiles would sort them against a sea of order:0 siblings
     and wreck the whole row, not just the intended pair.
     ⚠️ THIS LIST MUST COVER EVERY TILE, KEPT IN SYNC BY HAND — shipped a real
     bug 2026-07-31: Gadoknows was added to row B (61→62 tiles) without adding
     its nth-child(62) rule, so it fell back to the default order:0 and
     rendered FIRST on mobile instead of last, ahead of 61 siblings all with
     positive order values. Row A is at 61/61, row B now at 62/62 — recount
     both against the live roster any time an artist is added or removed. */
  .strip__track { display: flex; }
  .strip[data-dir="-1"] .atile:nth-child(1) { order: 1; }
  .strip[data-dir="-1"] .atile:nth-child(2) { order: 3; }
  .strip[data-dir="-1"] .atile:nth-child(3) { order: 2; }
  .strip[data-dir="-1"] .atile:nth-child(4) { order: 4; }
  .strip[data-dir="-1"] .atile:nth-child(5) { order: 5; }
  .strip[data-dir="-1"] .atile:nth-child(6) { order: 6; }
  .strip[data-dir="-1"] .atile:nth-child(7) { order: 7; }
  .strip[data-dir="-1"] .atile:nth-child(8) { order: 8; }
  .strip[data-dir="-1"] .atile:nth-child(9) { order: 9; }
  .strip[data-dir="-1"] .atile:nth-child(10) { order: 10; }
  .strip[data-dir="-1"] .atile:nth-child(11) { order: 11; }
  .strip[data-dir="-1"] .atile:nth-child(12) { order: 12; }
  .strip[data-dir="-1"] .atile:nth-child(13) { order: 13; }
  .strip[data-dir="-1"] .atile:nth-child(14) { order: 14; }
  .strip[data-dir="-1"] .atile:nth-child(15) { order: 15; }
  .strip[data-dir="-1"] .atile:nth-child(16) { order: 16; }
  .strip[data-dir="-1"] .atile:nth-child(17) { order: 17; }
  .strip[data-dir="-1"] .atile:nth-child(18) { order: 18; }
  .strip[data-dir="-1"] .atile:nth-child(19) { order: 19; }
  .strip[data-dir="-1"] .atile:nth-child(20) { order: 20; }
  .strip[data-dir="-1"] .atile:nth-child(21) { order: 21; }
  .strip[data-dir="-1"] .atile:nth-child(22) { order: 22; }
  .strip[data-dir="-1"] .atile:nth-child(23) { order: 23; }
  .strip[data-dir="-1"] .atile:nth-child(24) { order: 24; }
  .strip[data-dir="-1"] .atile:nth-child(25) { order: 25; }
  .strip[data-dir="-1"] .atile:nth-child(26) { order: 26; }
  .strip[data-dir="-1"] .atile:nth-child(27) { order: 27; }
  .strip[data-dir="-1"] .atile:nth-child(28) { order: 28; }
  .strip[data-dir="-1"] .atile:nth-child(29) { order: 29; }
  .strip[data-dir="-1"] .atile:nth-child(30) { order: 30; }
  .strip[data-dir="-1"] .atile:nth-child(31) { order: 31; }
  .strip[data-dir="-1"] .atile:nth-child(32) { order: 32; }
  .strip[data-dir="-1"] .atile:nth-child(33) { order: 33; }
  .strip[data-dir="-1"] .atile:nth-child(34) { order: 34; }
  .strip[data-dir="-1"] .atile:nth-child(35) { order: 35; }
  .strip[data-dir="-1"] .atile:nth-child(36) { order: 36; }
  .strip[data-dir="-1"] .atile:nth-child(37) { order: 37; }
  .strip[data-dir="-1"] .atile:nth-child(38) { order: 38; }
  .strip[data-dir="-1"] .atile:nth-child(39) { order: 39; }
  .strip[data-dir="-1"] .atile:nth-child(40) { order: 40; }
  .strip[data-dir="-1"] .atile:nth-child(41) { order: 41; }
  .strip[data-dir="-1"] .atile:nth-child(42) { order: 42; }
  .strip[data-dir="-1"] .atile:nth-child(43) { order: 43; }
  .strip[data-dir="-1"] .atile:nth-child(44) { order: 44; }
  .strip[data-dir="-1"] .atile:nth-child(45) { order: 45; }
  .strip[data-dir="-1"] .atile:nth-child(46) { order: 46; }
  .strip[data-dir="-1"] .atile:nth-child(47) { order: 47; }
  .strip[data-dir="-1"] .atile:nth-child(48) { order: 48; }
  .strip[data-dir="-1"] .atile:nth-child(49) { order: 49; }
  .strip[data-dir="-1"] .atile:nth-child(50) { order: 50; }
  .strip[data-dir="-1"] .atile:nth-child(51) { order: 51; }
  .strip[data-dir="-1"] .atile:nth-child(52) { order: 52; }
  .strip[data-dir="-1"] .atile:nth-child(53) { order: 53; }
  .strip[data-dir="-1"] .atile:nth-child(54) { order: 54; }
  .strip[data-dir="-1"] .atile:nth-child(55) { order: 55; }
  .strip[data-dir="-1"] .atile:nth-child(56) { order: 56; }
  .strip[data-dir="-1"] .atile:nth-child(57) { order: 57; }
  .strip[data-dir="-1"] .atile:nth-child(58) { order: 58; }
  .strip[data-dir="-1"] .atile:nth-child(59) { order: 59; }
  .strip[data-dir="-1"] .atile:nth-child(60) { order: 60; }
  .strip[data-dir="-1"] .atile:nth-child(61) { order: 61; }
  .strip[data-dir="1"] .atile:nth-child(1) { order: 3; }
  .strip[data-dir="1"] .atile:nth-child(2) { order: 2; }
  .strip[data-dir="1"] .atile:nth-child(3) { order: 1; }
  .strip[data-dir="1"] .atile:nth-child(4) { order: 4; }
  .strip[data-dir="1"] .atile:nth-child(5) { order: 5; }
  .strip[data-dir="1"] .atile:nth-child(6) { order: 6; }
  .strip[data-dir="1"] .atile:nth-child(7) { order: 7; }
  .strip[data-dir="1"] .atile:nth-child(8) { order: 8; }
  .strip[data-dir="1"] .atile:nth-child(9) { order: 9; }
  .strip[data-dir="1"] .atile:nth-child(10) { order: 10; }
  .strip[data-dir="1"] .atile:nth-child(11) { order: 11; }
  .strip[data-dir="1"] .atile:nth-child(12) { order: 12; }
  .strip[data-dir="1"] .atile:nth-child(13) { order: 13; }
  .strip[data-dir="1"] .atile:nth-child(14) { order: 14; }
  .strip[data-dir="1"] .atile:nth-child(15) { order: 15; }
  .strip[data-dir="1"] .atile:nth-child(16) { order: 16; }
  .strip[data-dir="1"] .atile:nth-child(17) { order: 17; }
  .strip[data-dir="1"] .atile:nth-child(18) { order: 18; }
  .strip[data-dir="1"] .atile:nth-child(19) { order: 19; }
  .strip[data-dir="1"] .atile:nth-child(20) { order: 20; }
  .strip[data-dir="1"] .atile:nth-child(21) { order: 21; }
  .strip[data-dir="1"] .atile:nth-child(22) { order: 22; }
  .strip[data-dir="1"] .atile:nth-child(23) { order: 23; }
  .strip[data-dir="1"] .atile:nth-child(24) { order: 24; }
  .strip[data-dir="1"] .atile:nth-child(25) { order: 25; }
  .strip[data-dir="1"] .atile:nth-child(26) { order: 26; }
  .strip[data-dir="1"] .atile:nth-child(27) { order: 27; }
  .strip[data-dir="1"] .atile:nth-child(28) { order: 28; }
  .strip[data-dir="1"] .atile:nth-child(29) { order: 29; }
  .strip[data-dir="1"] .atile:nth-child(30) { order: 30; }
  .strip[data-dir="1"] .atile:nth-child(31) { order: 31; }
  .strip[data-dir="1"] .atile:nth-child(32) { order: 32; }
  .strip[data-dir="1"] .atile:nth-child(33) { order: 33; }
  .strip[data-dir="1"] .atile:nth-child(34) { order: 34; }
  .strip[data-dir="1"] .atile:nth-child(35) { order: 35; }
  .strip[data-dir="1"] .atile:nth-child(36) { order: 36; }
  .strip[data-dir="1"] .atile:nth-child(37) { order: 37; }
  .strip[data-dir="1"] .atile:nth-child(38) { order: 38; }
  .strip[data-dir="1"] .atile:nth-child(39) { order: 39; }
  .strip[data-dir="1"] .atile:nth-child(40) { order: 40; }
  .strip[data-dir="1"] .atile:nth-child(41) { order: 41; }
  .strip[data-dir="1"] .atile:nth-child(42) { order: 42; }
  .strip[data-dir="1"] .atile:nth-child(43) { order: 43; }
  .strip[data-dir="1"] .atile:nth-child(44) { order: 44; }
  .strip[data-dir="1"] .atile:nth-child(45) { order: 45; }
  .strip[data-dir="1"] .atile:nth-child(46) { order: 46; }
  .strip[data-dir="1"] .atile:nth-child(47) { order: 47; }
  .strip[data-dir="1"] .atile:nth-child(48) { order: 48; }
  .strip[data-dir="1"] .atile:nth-child(49) { order: 49; }
  .strip[data-dir="1"] .atile:nth-child(50) { order: 50; }
  .strip[data-dir="1"] .atile:nth-child(51) { order: 51; }
  .strip[data-dir="1"] .atile:nth-child(52) { order: 52; }
  .strip[data-dir="1"] .atile:nth-child(53) { order: 53; }
  .strip[data-dir="1"] .atile:nth-child(54) { order: 54; }
  .strip[data-dir="1"] .atile:nth-child(55) { order: 55; }
  .strip[data-dir="1"] .atile:nth-child(56) { order: 56; }
  .strip[data-dir="1"] .atile:nth-child(57) { order: 57; }
  .strip[data-dir="1"] .atile:nth-child(58) { order: 58; }
  .strip[data-dir="1"] .atile:nth-child(59) { order: 59; }
  .strip[data-dir="1"] .atile:nth-child(60) { order: 60; }
  .strip[data-dir="1"] .atile:nth-child(61) { order: 61; }
  .strip[data-dir="1"] .atile:nth-child(62) { order: 62; }
}