/* Chroma — one stylesheet, no dependencies, no build step.
 *
 * The brief: Williamsburg nail studio, sleek, and cyberpunk only underneath.
 * The way that is kept honest here is a rule about where the neon is allowed
 * to go. Light, lines and numerals may be cyberpunk; anything a client has to
 * read to spend money may not. So:
 *
 *   - the two accents (orchid, ice) only ever appear as light: a glow, a
 *     hairline, a rule under a heading, a 1px edge that brightens on hover;
 *   - prices, service names and body copy are bone white on near-black at
 *     ordinary contrast, in ordinary faces, at ordinary sizes;
 *   - the only monospace on the page is on things that are not words -- the
 *     section numerals, the eyebrows, the durations.
 *
 * That split is what lets the page read as a salon rather than as a terminal,
 * while still looking like it belongs next to the rest of datarail.org.
 *
 * No web fonts. Nothing is fetched from anywhere, so the page cannot be made
 * slow or broken by a third party, and it renders the same offline.
 */

:root {
  /* Near-black with a blue cast rather than a grey one: the warm bone text
     and the orchid both sit better on it than they do on neutral grey. */
  --ink: #08080c;
  --ink-2: #0c0c13;
  --panel: #10101a;
  --panel-2: #14141f;

  --bone: #ece6dd;        /* body text */
  --bone-dim: #a7a29c;    /* notes, durations */
  --bone-faint: #6e6a67;  /* fine print */

  --orchid: #c9a7ff;
  --ice: #8ef3e4;
  --rose: #ffb7c8;

  --line: rgba(236, 230, 221, 0.12);
  --line-bright: rgba(236, 230, 221, 0.26);

  --serif: "Hoefler Text", "Didot", "Big Caslon", "Palatino Linotype", Palatino, Georgia, serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace;

  --shell: 1120px;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --radius: 14px;
}

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

/* The masthead is sticky, so a jump to #flights would otherwise land with the
   heading underneath it. Keep the two numbers in step. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font: 400 1rem/1.65 var(--sans);
  letter-spacing: 0.005em;
  overflow-x: hidden;
}

/* A single faint vertical wash down the page, so the dark is not flat. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(900px 600px at 15% -10%, rgba(201, 167, 255, 0.10), transparent 70%),
    radial-gradient(700px 500px at 95% 8%, rgba(142, 243, 228, 0.07), transparent 70%);
}

body > * { position: relative; z-index: 1; }

img { max-width: 100%; height: auto; display: block; }

a { color: var(--bone); text-decoration-color: var(--line-bright); text-underline-offset: 0.2em; }
a:hover { text-decoration-color: var(--orchid); }

em { font-style: italic; color: var(--bone); }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  z-index: 50;
  background: var(--panel);
  border: 1px solid var(--orchid);
  border-radius: 8px;
  padding: 0.6rem 1rem;
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--orchid);
  outline-offset: 3px;
}

/* --- Masthead ----------------------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(8, 8, 12, 0.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.masthead-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 72px;
  flex-wrap: wrap;
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
}

.wordmark-mark { flex: none; }

.wordmark-text { display: block; }

.wordmark-line {
  display: block;
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* The wordmark is the one place the chrome is allowed to be literal. */
  background: linear-gradient(104deg, #ffffff 0%, #cfd6e4 28%, #8c93a6 46%, #ffffff 62%, #cbb4ef 86%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.wordmark-sub {
  display: block;
  margin-top: 0.3rem;
  font: 400 0.64rem/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--bone-faint);
}

.masthead nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.4rem;
}

.masthead nav a {
  font: 400 0.76rem/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone-dim);
  text-decoration: none;
  padding: 0.4rem 0;
  border-bottom: 1px solid transparent;
}

.masthead nav a:hover {
  color: var(--bone);
  border-bottom-color: var(--orchid);
}

/* --- Hero --------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  padding: clamp(4.5rem, 13vw, 9rem) 0 clamp(3.5rem, 9vw, 6rem);
  border-bottom: 1px solid var(--line);
}

.hero-glow {
  position: absolute;
  left: 50%;
  top: -42%;
  width: 150%;
  aspect-ratio: 2 / 1;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(201, 167, 255, 0.24), rgba(142, 243, 228, 0.08) 58%, transparent 72%);
  filter: blur(8px);
  pointer-events: none;
}

/* The one overtly cyberpunk element on the page, and it is turned almost all
   the way down: a 64px grid at 4% opacity, faded out before it reaches the
   text. Any stronger and the page stops being a salon. */
.hero-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(236, 230, 221, 0.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(236, 230, 221, 0.055) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(120% 90% at 50% 0%, #000 10%, transparent 72%);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 10%, transparent 72%);
}

.eyebrow {
  margin: 0 0 1.4rem;
  font: 400 0.72rem/1.4 var(--mono);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--orchid);
}

.hero-title {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.9rem, 9.5vw, 6.5rem);
  line-height: 0.98;
  letter-spacing: -0.015em;
  max-width: 18ch;
}

/* The one animated thing on the page, and the only place the brand name is
   taken literally: a chrome gradient wider than the text it fills, slid across
   by a single custom property, with a bloom thrown behind the letters.
 *
 * Registering --shine with @property is what makes it animatable at all: an
 * unregistered custom property has no type, so the browser cannot interpolate
 * between two values of it and the drift would jump rather than slide.
 *
 * The text-shadow is the bloom. It works even though the text itself is
 * transparent, because a shadow is drawn from the glyph outline rather than
 * from the fill, so it lands behind the gradient instead of being clipped
 * away with it. Two of them: a tight orchid halo and a wide, faint ice one. */
@property --shine {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

.chrome {
  display: inline-block;
  font-style: italic;
  background-image: linear-gradient(
    100deg,
    #c6cddb 0%,
    #9aa1b4 12%,
    #ffffff 24%,
    #efe2ff 31%,
    #ffffff 38%,
    #a9ded6 50%,
    #9aa1b4 64%,
    #ffffff 78%,
    #d9c2ff 90%,
    #9fe9dd 100%
  );
  background-size: 240% 100%;
  background-position: var(--shine) 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  text-shadow:
    0 0 22px rgba(201, 167, 255, 0.30),
    0 0 64px rgba(142, 243, 228, 0.14);
  /* The drift with nothing driving it. Slow enough that it reads as light
     moving over the letters rather than as an animation playing. */
  animation: drift 19s ease-in-out infinite alternate;
}

@keyframes drift {
  from { --shine: 22%; }
  to   { --shine: 78%; }
}

/* Once the pointer, the scroll position or the tilt of a phone is driving the
   shine, the ambient drift gets out of the way: an animation outranks the
   inline value the script sets, so the two cannot share the property. */
.shine-live .chrome { animation: none; }

.hero-lede {
  margin: 1.8rem 0 0;
  max-width: 54ch;
  font-size: clamp(1.02rem, 2.2vw, 1.18rem);
  color: #d8d2ca;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin: 2.2rem 0 0;
}

.button {
  display: inline-block;
  padding: 0.85rem 1.6rem;
  border-radius: 999px;
  border: 1px solid var(--line-bright);
  background: linear-gradient(180deg, rgba(201, 167, 255, 0.18), rgba(201, 167, 255, 0.04));
  color: var(--bone);
  font: 500 0.78rem/1 var(--mono);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  text-decoration: none;
  transition: border-color 140ms ease, box-shadow 140ms ease, background-color 140ms ease;
}

.button:hover {
  border-color: var(--orchid);
  box-shadow: 0 0 0 1px rgba(201, 167, 255, 0.35), 0 10px 40px -18px rgba(201, 167, 255, 0.8);
}

.button-quiet {
  background: transparent;
  color: var(--bone-dim);
}

.button-quiet:hover { color: var(--bone); }

/* --- Sections ----------------------------------------------------------- */

.menu-head { padding: clamp(3.5rem, 8vw, 5.5rem) 0 0; }

.section-title {
  margin: 0 0 1.2rem;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 5vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.section-title::after {
  content: "";
  display: block;
  width: 72px;
  height: 1px;
  margin-top: 1rem;
  background: linear-gradient(90deg, var(--orchid), var(--ice) 60%, transparent);
}

.prose {
  margin: 0 0 1rem;
  max-width: 62ch;
  color: #cfc9c1;
}

.pricing-disclaimer {
  margin: 1.6rem 0 0;
  max-width: 62ch;
  padding: 1rem 1.2rem;
  border-left: 2px solid var(--rose);
  border-radius: 0 10px 10px 0;
  background: rgba(255, 183, 200, 0.06);
  font-size: 0.92rem;
  color: #d9d2cb;
}

.pricing-disclaimer strong { color: var(--bone); }

.card-section { padding: clamp(2rem, 5vw, 3rem) 0; }

.card {
  position: relative;
  padding: clamp(1.6rem, 4vw, 2.6rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, var(--panel-2), var(--panel) 42%, var(--ink-2));
  transition: border-color 160ms ease;
}

/* A hairline of light along the top edge of every card. It is the cheapest
   way to get the neon in without putting it anywhere near the prices. */
.card::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto -1px;
  height: 1px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(90deg, transparent, rgba(201, 167, 255, 0.55) 18%, rgba(142, 243, 228, 0.45) 62%, transparent);
  opacity: 0.75;
}

.card:hover { border-color: var(--line-bright); }

.card-head { margin-bottom: 1.8rem; }

.card-index {
  margin: 0 0 0.6rem;
  font: 400 0.72rem/1 var(--mono);
  letter-spacing: 0.22em;
  color: var(--bone-faint);
}

.card-head h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.6rem, 4vw, 2.3rem);
  line-height: 1.1;
}

.card-note {
  margin: 0.8rem 0 0;
  max-width: 58ch;
  color: var(--bone-dim);
  font-size: 0.95rem;
}

.card-foot {
  margin: 1.6rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px dashed var(--line);
  color: var(--bone-dim);
  font-size: 0.9rem;
}

.card-foot-tight { margin-top: 1.1rem; }

.fee-inline { color: var(--bone); font-variant-numeric: tabular-nums; }

.sub {
  margin: 0 0 1rem;
  font: 400 0.74rem/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ice);
}

.prose-block .sub { margin-top: 2rem; }
.prose-block .sub:first-child { margin-top: 0; }

/* --- Price lists -------------------------------------------------------- */

.prices {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Name and fee on one row, the duration under the name. The fee column is
   fixed and tabular so the numbers line up down the page -- a price list
   where the amounts do not align reads as an estimate. */
.price {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "name fee"
    "note fee";
  column-gap: 1.2rem;
  align-items: baseline;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
}

.prices > .price:last-child { border-bottom: 0; padding-bottom: 0; }

.price-name {
  grid-area: name;
  font-size: 1.04rem;
  color: var(--bone);
}

.price-note {
  grid-area: note;
  margin-top: 0.2rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--bone-dim);
  max-width: 52ch;
}

.price-fee {
  grid-area: fee;
  align-self: start;
  font: 400 1.04rem/1.5 var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--bone);
  white-space: nowrap;
}

.price-add .price-name { color: #ded8d0; }
.price-add .price-fee { color: var(--bone-dim); }

.tag {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.18rem 0.5rem 0.14rem;
  border: 1px solid rgba(142, 243, 228, 0.35);
  border-radius: 999px;
  font: 400 0.6rem/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ice);
  vertical-align: 0.1em;
}

/* --- Layout helpers ----------------------------------------------------- */

.split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.6rem);
}

.split-part > .prices { margin-top: 0; }

.prose-block { min-width: 0; }

.facts {
  padding: clamp(1.4rem, 3.5vw, 2rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel-2), var(--ink-2));
}

.fact-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.8rem 1.4rem;
  margin: 0;
}

.fact-list dt {
  font: 400 0.68rem/1.6 var(--mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bone-faint);
}

.fact-list dd {
  margin: 0;
  font-size: 0.95rem;
}

/* An unanswered question is shown as unanswered rather than filled in. */
.unknown { color: var(--bone-dim); font-style: italic; }

.fine {
  margin: 1.4rem 0 0;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--bone-faint);
  max-width: 60ch;
}

.studio {
  padding: clamp(3.5rem, 8vw, 6rem) 0 clamp(2rem, 5vw, 3rem);
  border-top: 1px solid var(--line);
  margin-top: clamp(2rem, 5vw, 3rem);
}

/* --- Book --------------------------------------------------------------- */

.book {
  padding: clamp(3.5rem, 9vw, 6.5rem) 0 clamp(4rem, 10vw, 7rem);
}

.book-inner {
  position: relative;
  padding: clamp(2rem, 6vw, 4rem);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 6px);
  overflow: hidden;
  background:
    radial-gradient(130% 110% at 100% 0%, rgba(201, 167, 255, 0.16), transparent 60%),
    radial-gradient(90% 120% at 0% 100%, rgba(142, 243, 228, 0.10), transparent 62%),
    linear-gradient(180deg, var(--panel-2), var(--ink-2));
}

.book-title {
  margin: 0 0 1.4rem;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.8rem, 5.4vw, 3.2rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
}

/* --- Footer ------------------------------------------------------------- */

.footer {
  border-top: 1px solid var(--line);
  padding: 2.4rem 0 3.4rem;
}

.footer-inner { display: grid; gap: 1rem; }

.footer-mark {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  font: 400 0.72rem/1.4 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

.footer .fine { margin: 0; }

/* --- Wider screens ------------------------------------------------------ */

@media (min-width: 720px) {
  .prices-two {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: clamp(2rem, 5vw, 3.5rem);
  }
  /* In two columns the last item of the first column is not the last item of
     the list, so the border has to come back everywhere and go away only on
     the genuinely final row of each column. Simpler to keep it on all rows. */
  .prices-two > .price:last-child { border-bottom: 1px solid var(--line); padding-bottom: 0.85rem; }

  .split-three { grid-template-columns: repeat(3, 1fr); }
  .split-cards { grid-template-columns: 1fr 1fr; align-items: start; }
  .split-visit { grid-template-columns: 1.25fr 1fr; align-items: start; }
}

@media (max-width: 719px) {
  .masthead { position: static; }
  .masthead-inner { min-height: 0; }
  .masthead nav { gap: 0.3rem 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Printing the menu is a real thing a salon does. Give it ink-on-paper. */
@media print {
  :root { --bone: #111; --bone-dim: #444; --bone-faint: #666; --line: #ccc; }
  body { background: #fff; color: #111; }
  body::before, .hero-glow, .hero-grid, .masthead nav, .button { display: none; }
  .card, .facts, .book-inner { border-color: #ccc; background: #fff; }
  .card::before { display: none; }
  .wordmark-line, .chrome { color: #111; background: none; -webkit-text-fill-color: #111; }
}
