/* ============================================================
   THE CRAB HOUSE — Hattiesburg, MS

   A counter-service seafood joint. Five things a visitor wants:
   what this is, what's good, what it costs, whether it's open,
   and where it is. The site does those five things and stops.

   Kraft ground, black ink, one red. Two type sizes that matter.
   Everything set large with room around it.
   ============================================================ */

:root {
  --paper:  #F4ECDE;
  --paper-2:#E9DFCB;
  --paper-3:#FCF9F3;
  --ink:    #1A1712;
  --muted:  #6B6154;
  --red:    #C4301B;
  --red-hi: #E24A31;

  --sign: 'Anton', 'Arial Narrow', Impact, sans-serif;
  --read: 'Newsreader', Georgia, 'Times New Roman', serif;

  --pad: clamp(1.15rem, 5vw, 4rem);
  --max: 1080px;              /* one comfortable column, not a broadsheet */
  --gap: clamp(4.5rem, 11vw, 9rem);   /* the space between sections */
  --ease: cubic-bezier(.2,.7,.3,1);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { background: var(--paper); scroll-behavior: smooth; }

/* ---------- the paper ----------
   Two layers of turbulence multiplied into the background colour: a fine
   tooth, and a much coarser mottle for the unevenness real stock has. They
   are background layers rather than an overlay element, so they sit under
   every bit of content automatically — no stacking context to manage, and
   nothing lands on top of the photographs. Multiply means they only ever
   darken, so the warmth of the paper survives.

   Combined they move the ground by about 13 levels out of 255 — under 5%,
   which is enough to stop it reading as a flat fill and not enough to
   notice as an effect. stitchTiles keeps the tiles seamless, and the
   mottle is set large so it repeats only a handful of times down the
   page. */
:root {
  --tooth: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='t'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23t)' opacity='.075'/%3E%3C/svg%3E");
  --mottle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='900'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.013' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='900' height='900' filter='url(%23m)' opacity='.08'/%3E%3C/svg%3E");
}
body {
  background-color: var(--paper);
  background-image: var(--tooth), var(--mottle);
  background-size: 200px 200px, 1200px 1200px;
  background-blend-mode: multiply, multiply;
  color: var(--ink);
  font-family: var(--read);
  font-size: clamp(1.08rem, 1.35vw, 1.22rem);
  line-height: 1.7;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--red); color: var(--paper); }
:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }

.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--pad); }

.sign { font-family: var(--sign); font-weight: 400; text-transform: uppercase; line-height: .95; }
.skip {
  position: absolute; left: 50%; top: 0; transform: translate(-50%,-130%);
  background: var(--ink); color: var(--paper); padding: .8rem 1.3rem; z-index: 300;
  font-family: var(--sign); text-transform: uppercase; letter-spacing: .1em;
  transition: transform .2s;
}
.skip:focus { transform: translate(-50%,0); }

/* ============ BUTTONS ============ */
.btn {
  display: inline-block; font-family: var(--sign); text-transform: uppercase;
  letter-spacing: .06em; font-size: 1.12rem; padding: .85em 1.7em;
  border: 2px solid var(--ink); transition: background .2s, color .2s, border-color .2s;
}
.btn-red { background: var(--red); border-color: var(--red); color: #fff; }
.btn-red:hover { background: var(--ink); border-color: var(--ink); }
.btn-plain:hover { background: var(--ink); color: var(--paper); }

/* ============ HEADER ============ */
/* One tier. Name, whether we're open, one button. */
.top { border-bottom: 2px solid var(--ink); background: var(--paper); position: sticky; top: 0; z-index: 100; }
.top-in {
  max-width: var(--max); margin: 0 auto; padding: clamp(.85rem,1.8vw,1.15rem) var(--pad);
  display: flex; align-items: center; justify-content: space-between; gap: 1.2rem;
}
.brand { font-family: var(--sign); text-transform: uppercase; font-size: clamp(1.35rem,2.8vw,1.9rem); line-height: 1; }
.brand i { font-style: normal; color: var(--red); }
.top-right { display: flex; align-items: center; gap: clamp(.8rem,2vw,1.6rem); }
.top-nav { display: flex; gap: clamp(1rem,2.2vw,1.9rem); }
.top-nav a { font-family: var(--sign); text-transform: uppercase; font-size: 1rem; letter-spacing: .05em; color: var(--muted); }
.top-nav a:hover { color: var(--red); }
.top .btn { font-size: 1rem; padding: .6em 1.15em; }
@media (max-width: 760px) { .top-nav { display: none; } }

/* ============ FRONT ============ */
/* One column. Nothing beside it to read at the same time. */
.front { padding-top: clamp(3rem,7vw,6rem); text-align: center; }
.front h1 {
  font-family: var(--sign); text-transform: uppercase;
  font-size: clamp(2.7rem, 9vw, 6.2rem); line-height: .92; letter-spacing: -.01em;
}
.front h1 .lift { display: block; overflow: hidden; padding-bottom: .06em; margin-bottom: -.06em; }
.front h1 .lift.red { color: var(--red); }
.front h1 .lift > span { display: block; }
.front-sub {
  margin: clamp(1.4rem,3vw,2.1rem) auto 0; max-width: 36ch;
  font-size: clamp(1.15rem,1.9vw,1.45rem); line-height: 1.55; color: var(--muted);
}
.front-btns { margin-top: clamp(1.8rem,3.5vw,2.6rem); display: flex; gap: .8rem; justify-content: center; flex-wrap: wrap; }

/* the one strip of facts, on a single line */
.facts {
  margin-top: clamp(2rem,4vw,3rem); border-block: 2px solid var(--ink);
  display: flex; justify-content: center; align-items: center;
  gap: clamp(.9rem,3vw,2.6rem); flex-wrap: wrap;
  padding: 1rem var(--pad); font-size: 1.05rem;
}
.facts b { font-family: var(--sign); text-transform: uppercase; letter-spacing: .04em; font-weight: 400; font-size: 1.1rem; }
.facts .is-open  { color: var(--red); }
.facts .is-shut  { color: var(--muted); }
.facts .dot { color: var(--muted); }
.facts a:hover { color: var(--red); }
@media (max-width: 620px) { .facts { gap: .35rem 1rem; font-size: .98rem; } .facts .dot { display: none; } }

.front-shot { margin-top: clamp(2rem,4vw,3rem); aspect-ratio: 2/1; background: #000; position: relative; overflow: hidden; }
/* the picture is 18% taller than its frame and hung 9% above it, so the
   drift has the same slack in both directions and never shows an edge */
.front-shot img { position: absolute; top: -9%; left: 0; width: 100%; height: 118%; object-fit: cover; will-change: transform; }
@media (max-width: 640px) { .front-shot { aspect-ratio: 4/3; } }

/* ============ SECTION HEADS ============ */
.head { margin-top: var(--gap); text-align: center; }
.head h2 {
  font-family: var(--sign); text-transform: uppercase;
  font-size: clamp(2.1rem,5.4vw,3.4rem); line-height: 1; letter-spacing: -.005em;
}
.head h2 i { font-style: normal; color: var(--red); }
.head p { margin-top: .7rem; color: var(--muted); font-size: 1.08rem; }
.head::after {
  content: ''; display: block; width: 70px; height: 3px; background: var(--ink);
  margin: clamp(1.2rem,2.4vw,1.8rem) auto 0;
  transform: scaleX(0); transition: transform .8s cubic-bezier(.16,1,.3,1) .2s;
}
.head.in::after { transform: scaleX(1); }

/* ============ MENU ============ */
/* One column, big rows, plenty of air. Eight lines, not twenty. */
.menu { margin-top: clamp(2.2rem,4.5vw,3.4rem); }
.group + .group { margin-top: clamp(2.6rem,5vw,4rem); }
.group h3 {
  font-family: var(--sign); text-transform: uppercase; font-size: 1.35rem; letter-spacing: .08em;
  color: var(--red); padding-bottom: .6rem; margin-bottom: .4rem; position: relative;
}
.group h3::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--ink);
  transform: scaleX(0); transform-origin: left;
  transition: transform .9s cubic-bezier(.16,1,.3,1);
}
.group.in h3::after { transform: scaleX(1); }
.row { display: block; padding: 1.15rem 0; border-bottom: 1px solid rgba(26,23,18,.18); }
.row-line { display: flex; align-items: baseline; gap: .6rem; }
.row-name { font-size: clamp(1.25rem,2.1vw,1.6rem); font-weight: 600; line-height: 1.2; }
.row-dots { flex: 1; position: relative; transform: translateY(-.3em); min-width: 1.5rem; height: 2px; }
.row-dots i {
  position: absolute; inset: 0; border-bottom: 2px dotted rgba(26,23,18,.28);
  transform: scaleX(0); transform-origin: left;
  transition: transform .9s cubic-bezier(.16,1,.3,1) .15s;
}
.row-price { font-family: var(--sign); font-size: clamp(1.25rem,2.1vw,1.55rem); letter-spacing: .01em; white-space: nowrap; transition: color .2s, transform .3s var(--ease); }
a.row:hover .row-price { transform: translateX(-.2rem); }
.row-price.ask { font-size: 1rem; letter-spacing: .06em; color: var(--muted); }
.row-note { display: block; margin-top: .3rem; color: var(--muted); font-size: 1.02rem; line-height: 1.5; max-width: 52ch; }
a.row { transition: background .18s, padding .18s; }
a.row:hover { background-color: rgba(26,23,18,.045); padding-inline: .7rem; }
a.row:hover .row-price { color: var(--red); }

.menu-more { margin-top: clamp(2.4rem,4.5vw,3.4rem); text-align: center; }
.menu-more p { color: var(--muted); max-width: 46ch; margin: 0 auto 1.4rem; }

/* ============ PHOTOS ============ */
/* Six, all the same shape. Nothing to work out. */
.shots { display: grid; grid-template-columns: repeat(3,1fr); gap: clamp(.7rem,1.6vw,1.2rem); margin-top: clamp(2.2rem,4.5vw,3.4rem); }
.shots figure { aspect-ratio: 1; background: #000; overflow: hidden; position: relative; }
/* the restaurant's own dish photos carry a burned-in red caption in the
   lower left; these are shot on black, so a black fade removes it without
   leaving a mark. Only on those — it would show on a daylight photo. */
.shots figure.dish::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, #000 0%, rgba(0,0,0,.96) 15%, rgba(0,0,0,0) 34%);
}
.shots img { position: absolute; top: -8%; left: 0; width: 100%; height: 116%; object-fit: cover; will-change: transform; }
.shots figure { transition: transform .4s var(--ease); }
.shots figure:hover { transform: translateY(-4px); }
@media (max-width: 760px) { .shots { grid-template-columns: repeat(2,1fr); } }

/* ============ SAYS ============ */
.says { display: grid; grid-template-columns: repeat(3,1fr); gap: clamp(1.8rem,4vw,3.2rem); margin-top: clamp(2.2rem,4.5vw,3.4rem); }
@media (max-width: 820px) { .says { grid-template-columns: 1fr; max-width: 34rem; margin-inline: auto; } }
.say { text-align: center; }
.say-stars { color: var(--red); letter-spacing: .2em; font-size: 1rem; }
.say p { margin-top: .7rem; font-size: 1.12rem; line-height: 1.6; }
.say cite { display: block; margin-top: .9rem; font-family: var(--sign); text-transform: uppercase; font-size: .9rem; letter-spacing: .08em; color: var(--muted); font-style: normal; }

/* ============ VISIT ============ */
.visit { margin-top: clamp(2.2rem,4.5vw,3.4rem); display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,4.5rem); }
@media (max-width: 720px) { .visit { grid-template-columns: 1fr; gap: 2.6rem; } }
.visit h3 { font-family: var(--sign); text-transform: uppercase; font-size: 1.2rem; letter-spacing: .08em; color: var(--red); padding-bottom: .55rem; border-bottom: 2px solid var(--ink); margin-bottom: .5rem; }
.hours { width: 100%; border-collapse: collapse; }
.hours td { padding: .78rem 0; border-bottom: 1px solid rgba(26,23,18,.18); font-size: 1.08rem; }
.hours td:last-child { text-align: right; font-family: var(--sign); font-size: 1.08rem; letter-spacing: .02em; }
.hours tr.now td { color: var(--red); }
.visit address { font-style: normal; font-size: clamp(1.35rem,2.6vw,1.75rem); line-height: 1.4; font-weight: 600; margin-top: 1rem; }
.visit address a:hover { color: var(--red); }
.big-tel { display: inline-block; margin-top: 1rem; font-family: var(--sign); font-size: clamp(1.9rem,4.4vw,2.6rem); letter-spacing: .01em; }
.big-tel:hover { color: var(--red); }
.visit-note { margin-top: 1rem; color: var(--muted); font-size: 1.02rem; }
.visit-btns { margin-top: 1.6rem; display: flex; gap: .7rem; flex-wrap: wrap; }

/* ============ FOOTER ============ */
.foot {
  margin-top: var(--gap); border-top: 2px solid var(--ink);
  background-color: var(--paper-2);
  background-image: var(--tooth), var(--mottle);
  background-size: 200px 200px, 1200px 1200px;
  background-blend-mode: multiply, multiply;
}
.foot-in {
  max-width: var(--max); margin: 0 auto; padding: clamp(2.2rem,4vw,3rem) var(--pad);
  display: flex; justify-content: space-between; align-items: flex-start; gap: 1.5rem 2.5rem; flex-wrap: wrap;
}
.foot-mark { font-family: var(--sign); text-transform: uppercase; font-size: 1.7rem; line-height: 1; }
.foot-mark i { font-style: normal; color: var(--red); }
.foot-in p { margin-top: .5rem; color: var(--muted); font-size: 1rem; max-width: 30ch; }
.foot-links { display: flex; flex-direction: column; gap: .4rem; }
.foot-links a { font-size: 1.02rem; }
.foot-links a:hover { color: var(--red); }
.foot-bar { border-top: 1px solid rgba(26,23,18,.2); }
.foot-bar div {
  max-width: var(--max); margin: 0 auto; padding: 1rem var(--pad);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-size: .92rem; color: var(--muted);
}
.foot-bar a:hover { color: var(--red); }

/* ============ THE BAND ============ */
/* Full width, edge to edge, always moving. It breaks the column and gives
   the page something alive in it without asking to be read. */
.band {
  margin-top: var(--gap); overflow: hidden; background: #000;
  border-block: 2px solid var(--ink);
}
.band-track { display: flex; width: max-content; animation: drift 55s linear infinite; }
.band-cell { position: relative; flex: none; display: block; width: clamp(170px, 22vw, 280px); aspect-ratio: 1; }
.band-cell img { width: 100%; height: 100%; object-fit: cover; opacity: .92; transition: opacity .3s; }
/* same burned-in caption as the grid, same black fade to cover it */
.band-cell::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, #000 0%, rgba(0,0,0,.96) 15%, rgba(0,0,0,0) 34%);
}
.band:hover .band-track { animation-play-state: paused; }
.band-cell:hover img { opacity: 1; }
@keyframes drift { to { transform: translateX(-50%); } }

/* ============ ARRIVAL ============ */
/* Four moves, not one. Copy lifts, headings' rules draw, photographs wipe
   up from nothing, and menu rows come in one after another. */
.up { opacity: 0; transform: translateY(18px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.up.in { opacity: 1; transform: none; }

/* masked line: the words are pushed below their own box and slide up */
.lift { display: block; overflow: hidden; }
.lift > span { display: block; transform: translateY(112%); transition: transform 1s cubic-bezier(.16,1,.3,1); }
.ready .lift > span, .in .lift > span { transform: none; }
.front h1 .lift:nth-of-type(2) > span { transition-delay: .12s; }

/* menu rows arrive in sequence and pull their leader across behind them */
.row { opacity: 0; transform: translateY(16px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.group.in .row { opacity: 1; transform: none; }
.group.in .row-dots i { transform: scaleX(1); }
.group.in .row:nth-child(2) { transition-delay: .06s; }
.group.in .row:nth-child(3) { transition-delay: .14s; }
.group.in .row:nth-child(4) { transition-delay: .22s; }
.group.in .row:nth-child(5) { transition-delay: .30s; }
.group.in .row:nth-child(3) .row-dots i { transition-delay: .21s; }
.group.in .row:nth-child(4) .row-dots i { transition-delay: .29s; }
.group.in .row:nth-child(5) .row-dots i { transition-delay: .37s; }

/* photographs wipe up out of black and settle out of a slight push in */
.shots figure { clip-path: inset(0 0 100% 0); transition: clip-path .9s cubic-bezier(.16,1,.3,1), transform .4s var(--ease); }
.shots figure.in { clip-path: inset(0 0 0 0); }
.shots figure:nth-child(2), .shots figure:nth-child(5) { transition-delay: .1s; }
.shots figure:nth-child(3), .shots figure:nth-child(6) { transition-delay: .2s; }

/* the open light breathes while the kitchen is open */
.facts .is-open::after {
  content: ''; display: inline-block; width: .5em; height: .5em; margin-left: .5em;
  border-radius: 50%; background: var(--red); vertical-align: .05em;
  animation: breathe 2.6s ease-in-out infinite;
}
@keyframes breathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.82); } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .up, .row { opacity: 1 !important; transform: none !important; transition: none !important; }
  .lift > span { transform: none !important; }
  .row-dots i, .head::after, .group h3::after { transform: scaleX(1) !important; }
  .shots figure { clip-path: none !important; }
  .band-track { animation: none !important; }
  .facts .is-open::after { animation: none !important; }
  /* iteration-count matters as much as duration: without it the infinite
     drift and breathe keep looping thousands of times a second */
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ============ NARROW ============ */
@media (max-width: 560px) {
  /* two buttons of different lengths stacked read as a mistake */
  .front-btns { display: grid; grid-template-columns: 1fr; gap: .7rem; }
  .visit-btns { display: grid; grid-template-columns: 1fr; gap: .7rem; }
  .btn { text-align: center; }
  .front h1 { font-size: clamp(2.4rem, 11vw, 3.4rem); }
  .row-name { font-size: 1.22rem; }
  .top .btn { font-size: .95rem; padding: .58em 1.05em; }
}
