/*
  Designed and developed by Wave Agency - waveagency.com
*/

/* ============================================================
   HOSHI, the pre-launch holding page.
   Sumi ink ground, washi paper type, marked in persimmon (kaki), exactly the
   tokens the full site uses. The recurring mark is the hoshi point: a hairline
   cross with a solid center, the way a go board marks its nine 星.

   This file is deliberately standalone rather than an import of the site's
   styles.css. The holding page ships on its own and outlives none of it: the
   day the real site deploys, this whole directory stops being served. Sharing
   a stylesheet would mean a change to the site risking the one page that is
   actually live.
   ============================================================ */

/* ---------- Fonts (self-hosted, latin) ---------- */
@font-face{font-family:"Hanken Grotesk";src:url("../../fonts/hanken-grotesk-var.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap;}
@font-face{font-family:"Bodoni Moda";src:url("../../fonts/bodoni-moda-var-italic.woff2") format("woff2");font-weight:400 900;font-style:italic;font-display:swap;}

:root{
  --midnight:#14161A;
  --cream:#F5F2EC;
  --kaki:#B04226;
  --kaki-soft:#DE8C63;
  --line:rgba(245,242,236,.16);
  --line-soft:rgba(245,242,236,.10);

  --display:"Bodoni Moda",Didot,"Bodoni MT",Georgia,serif;
  --body:"Hanken Grotesk",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

  /* Square, everywhere. The room is all straight lines and a softened corner
     reads as a web convention rather than as this restaurant. */
  --radius:0;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  overflow-x:hidden;
  background:var(--midnight);
  color:var(--cream);
  font-family:var(--body);
  font-size:1rem;
  line-height:1.7;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  min-height:100vh;
  /* svh, so the mobile browser's own chrome cannot crop the composition. */
  min-height:100svh;
  display:flex;
  flex-direction:column;
}
/* height:auto is load-bearing. Every <img> carries width/height attributes so
   the browser reserves space, but without this the attribute height becomes a
   *used* height and any CSS sizing on the image is silently ignored. */
img{max-width:100%;height:auto;display:block;}
a{color:inherit;text-decoration:none;}
:focus-visible{outline:2px solid var(--kaki-soft);outline-offset:4px;}
::selection{background:var(--kaki);color:var(--cream);}

/* ---------- The ground ----------
   Four stacked layers, all fixed to the viewport and painted behind the
   content on negative z-indexes: ink (the canvas), the blurred wood texture, a
   lamplit warm glow with a vignette, and a fiber grain. They hang off the BODY
   rather than off .stage so that the footer stands on the same ground and the
   printed frame can enclose the whole page. A frame that stops short of the
   footer reads as a component, not as a card. */
body::before,
body::after{
  content:"";
  position:fixed;
  inset:0;
  pointer-events:none;
}
/* The photograph is held right down and blurred to nothing in the file itself.
   It is placeholder stock and the room is not built yet, so it may only ever
   read as texture, never as "our room". */
body::before{
  z-index:-3;
  background:url("../img/texture.webp") center/cover no-repeat;
  opacity:.10;
}
body::after{
  z-index:-2;
  background-image:
    radial-gradient(118% 78% at 50% -10%, rgba(222,140,99,.17), transparent 58%),
    radial-gradient(112% 108% at 50% 40%, transparent 26%, rgba(0,0,0,.62) 100%);
}
.grain{
  position:fixed;
  inset:0;
  z-index:-1;
  pointer-events:none;
  /* A faint fiber, the washi-paper equivalent on a dark ground. Inline SVG so
     it costs no request; the CSP allows data: on img-src for exactly this. */
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27160%27 height=%27160%27%3E%3Cfilter id=%27n%27%3E%3CfeTurbulence type=%27fractalNoise%27 baseFrequency=%27.82%27 numOctaves=%273%27/%3E%3C/filter%3E%3Crect width=%27160%27 height=%27160%27 filter=%27url(%23n)%27 opacity=%27.55%27/%3E%3C/svg%3E");
  opacity:.05;
  mix-blend-mode:overlay;
}

/* ---------- The printed frame ----------
   A hairline inset from the viewport edge rather than a box around the type:
   it makes the whole page read as one letterpress card, which is what the
   client's own placeholder was reaching for. Fixed, so it holds its inset on a
   phone where the address block can push the page past one screen. */
.frame{
  position:fixed;
  inset:clamp(.85rem,2.4vw,2.1rem);
  border:1px solid var(--line-soft);
  pointer-events:none;
  z-index:1;
}

.stage{
  flex:1;
  display:grid;
  /* minmax(0,1fr) and min-width:0 below are both load-bearing. A grid item
     defaults to min-width:auto, and the min-content contribution of an <img>
     is its INTRINSIC width, 1600px for the wordmark, because a percentage
     max-width is ignored for intrinsic sizing. Without them the card is
     sixteen hundred pixels wide and the page scrolls sideways on a phone. */
  grid-template-columns:minmax(0,1fr);
  place-items:center;
  /* Less padding at the foot than at the head: the footer bar below already
     occupies space inside the frame, so symmetric padding optically drops the
     whole composition. */
  padding:clamp(3.75rem,11vh,7.5rem) clamp(1.5rem,7vw,4rem) clamp(2.25rem,6vh,4.5rem);
}

.card{
  position:relative;
  z-index:2;
  width:100%;
  min-width:0;
  max-width:44rem;
  text-align:center;
}

/* ---------- Mark and eyebrow ---------- */
.mark{
  margin:0 auto clamp(1.1rem,2.4vw,1.6rem);
  display:block;
  width:22px;
  height:22px;
}
.mark__arm{fill:var(--kaki-soft);}
.mark__dot{fill:var(--kaki);}

.eyebrow{
  margin:0 0 clamp(2.1rem,5vw,3.1rem);
  display:flex;
  align-items:center;
  justify-content:center;
  gap:clamp(.9rem,3vw,1.5rem);
  font-size:.7rem;
  font-weight:500;
  text-transform:uppercase;
  color:var(--kaki-soft);
}
/* Letterspacing is added to the RIGHT of every glyph including the last, which
   pushes a centered line half a space off center. The negative margin gives the
   trailing space back. It lives on the span, not the flex container, because
   text-indent has no effect on a flex item. */
.eyebrow span{letter-spacing:.42em;margin-right:-.42em;}
.eyebrow::before,
.eyebrow::after{
  content:"";
  height:1px;
  width:clamp(1.75rem,9vw,4.5rem);
  background:linear-gradient(90deg,transparent,var(--line));
}
.eyebrow::after{background:linear-gradient(270deg,transparent,var(--line));}

/* ---------- The drawn lockup ----------
   Uppercase, as the client supplied it. Both are the real artwork rather than
   type set to look like it, so the wordmark here and the wordmark on their
   printed matter are provably the same drawing. */
.wordmark{
  /* 88% rather than 100%: the 32rem cap is what governs on a desktop, but on a
     phone a full-width mark lands twelve pixels from the printed frame and
     reads as a collision with it. */
  width:min(88%,32rem);
  margin:0 auto;
}
.descriptor{
  width:min(74%,18.5rem);
  margin:clamp(1.25rem,3vw,1.9rem) auto 0;
  opacity:.66;
}

/* ---------- Copy ---------- */
.lead{
  margin:clamp(2.4rem,5.5vw,3.4rem) auto 0;
  max-width:31rem;
  font-family:var(--display);
  font-style:italic;
  /* Bodoni carries an optical-size axis and it is not decoration. Its default
     instance is drawn for display sizes, where the hairlines are meant to be
     thinned by a large render; left there at text size the commas and full
     stops all but vanish on a dark ground. */
  font-variation-settings:"opsz" 16;
  font-size:clamp(1.08rem,2.3vw,1.32rem);
  line-height:1.62;
  color:rgba(245,242,236,.80);
}

.divider{
  width:clamp(3rem,12vw,5.5rem);
  height:1px;
  margin:clamp(2.2rem,5vw,3rem) auto;
  border:0;
  background:var(--line);
}

.meta{
  margin:0;
  font-size:.86rem;
  line-height:1.9;
  letter-spacing:.055em;
  color:rgba(245,242,236,.62);
}
.meta strong{
  display:block;
  font-weight:500;
  letter-spacing:.09em;
  color:rgba(245,242,236,.88);
}


/* ---------- Foot ---------- */
.foot{
  position:relative;
  z-index:2;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:.5rem 1.5rem;
  padding:0 clamp(2rem,7vw,5rem) clamp(1.9rem,4.5vw,2.9rem);
  font-size:.72rem;
  letter-spacing:.09em;
  color:rgba(245,242,236,.55);
}
.foot a{
  border-bottom:1px solid transparent;
  transition:color .32s var(--ease),border-color .32s var(--ease);
}
.foot a:hover,
.foot a:focus-visible{color:var(--cream);border-bottom-color:var(--line);}
@media (max-width:640px){
  .foot{justify-content:center;text-align:center;}
}

/* A laptop is routinely 768px tall and this composition is close to that on
   its own. Tightening the vertical rhythm on a short-but-wide viewport keeps
   the whole card on one screen, which is the entire job of a holding page:
   nobody scrolls one. Width-gated so a phone, where scrolling is normal and
   the type is already tight, is left alone. */
@media (min-width:720px) and (max-height:860px){
  .stage{padding-block:clamp(2.25rem,6.5vh,4.5rem) clamp(1.5rem,4vh,3rem);}
  .eyebrow{margin-bottom:clamp(1.5rem,3.5vh,2.4rem);}
  .lead{margin-top:clamp(1.6rem,4vh,2.6rem);}
  .divider{margin-block:clamp(1.4rem,3.2vh,2.2rem);}
  .foot{padding-bottom:clamp(1.25rem,3vh,2rem);}
}

/* ---------- Entrance ----------
   Every rule here is gated on `.anim`, which holding.js adds to <html> before
   the first paint. That is the point: if the script never runs, nothing is
   hidden and the page renders in full. See the comment at the top of
   holding.js for why it is a transition and not a keyframe animation. */
.anim .reveal{
  opacity:0;
  transform:translateY(14px);
  transition:opacity 1s var(--ease),transform 1s var(--ease);
  will-change:opacity,transform;
}
.anim.in .reveal{opacity:1;transform:none;}
.anim.in .reveal:nth-child(1){transition-delay:.05s;}
.anim.in .reveal:nth-child(2){transition-delay:.14s;}
.anim.in .reveal:nth-child(3){transition-delay:.24s;}
.anim.in .reveal:nth-child(4){transition-delay:.34s;}
.anim.in .reveal:nth-child(5){transition-delay:.44s;}
.anim.in .reveal:nth-child(6){transition-delay:.52s;}
.anim.in .reveal:nth-child(7){transition-delay:.60s;}
.anim.in .reveal:nth-child(8){transition-delay:.66s;}

/* Set by holding.js when the document loads hidden. transition:none matters:
   adding the end state alone only changes what the stalled transition is
   heading towards, and the page stays blank. */
.anim.no-anim .reveal{opacity:1 !important;transform:none !important;transition:none !important;}

@media (prefers-reduced-motion:reduce){
  .anim .reveal{opacity:1;transform:none;transition:none;}
}
