/* Omoshiro Earring Company — storefront.
   Vanilla CSS, no build step, no third-party requests (which is what lets the
   privacy page say the site loads nothing from anyone else).

   DIRECTION — "the vitrine".
   Every piece here is usually the only one of its kind, and no two pieces share
   a colour: brass gold, seafoam, persimmon, oxidised charcoal, indigo, lichen.
   So the shell supplies no colour of its own. The palette is achromatic paper,
   ink and hairlines, with one desaturated indigo reserved strictly for things
   you can interact with. The photographs are the only colour on the page.

   Contrast, checked when the tokens were chosen rather than afterwards:
   ink/paper 15.8:1 · ash/paper 5.4:1 · indigo/paper 9.6:1 · white/indigo 9.2:1 */

:root {
  color-scheme: light;

  --paper: #f5f5f2;   /* gallery wall — cool bone, deliberately not cream */
  --plate: #ffffff;   /* photographs sit on true white so colours read true */
  --ink:   #17181a;
  --ash:   #63666a;   /* secondary text */
  --hair:  #dcdcd6;   /* every rule on the site is one of these */
  --indigo:#24405e;   /* interactive only — never decorative */

  /* Mincho renders おもしろ properly instead of falling back mid-word, and it
     is the one place this site is allowed a voice above a whisper. */
  --display: "Hiragino Mincho ProN", "Yu Mincho", YuMincho, "Songti SC", "Noto Serif JP", serif;
  --text: "Helvetica Neue", Helvetica, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  /* A museum label: small, tracked, upper. Used for every piece of data that
     is data rather than prose. */
  --label-size: 0.6875rem;
  --label-track: 0.16em;

  --measure: 34rem;   /* prose */
  --wide: 60rem;      /* page */
  --gutter: 1.5rem;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--text);
  font-size: 0.9375rem;
  line-height: 1.75;
  letter-spacing: 0.005em;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--indigo); text-decoration-thickness: 1px; text-underline-offset: 0.2em; }

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

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--ink); color: var(--paper);
  padding: 0.75rem 1.25rem; text-decoration: none;
}
.skip-link:focus { left: 0; }

/* --- The label voice ----------------------------------------------------- */

.label,
.specimen,
.card-stock,
.site-header nav,
.footer-nav,
.rates thead th,
.cart-table thead th,
.materials dt,
.fine {
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  line-height: 1.6;
}

/* --- Chrome -------------------------------------------------------------- */

.banner {
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  padding: 0.7rem var(--gutter);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  max-width: var(--wide);
  margin: 0 auto;
  width: 100%;
  padding: 2rem var(--gutter) 1.25rem;
  border-bottom: 1px solid var(--hair);
}

.wordmark {
  font-family: var(--display);
  text-decoration: none;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  line-height: 1;
  padding-block: 0.25rem;
}
.wordmark-jp { font-size: 1.0625rem; letter-spacing: 0.12em; }
.wordmark-en { font-size: 0.8125rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--ash); }

/* The nav may wrap: "Cart(10)" pushed it past a 320px screen. The links carry
   enough padding to be 24px targets without moving their baselines. */
.site-header nav { display: flex; flex-wrap: wrap; gap: 0 1.75rem; align-items: baseline; }
@media (max-width: 24rem) { .site-header nav { column-gap: 1.25rem; } }
.site-header nav a { color: var(--ash); text-decoration: none; padding-block: 0.25rem; }
.site-header nav a:hover { color: var(--ink); }
.site-header nav a[aria-current="page"] { color: var(--ink); box-shadow: 0 1px 0 var(--ink); }

.cart-count { font-variant-numeric: tabular-nums; margin-left: 0.2em; }
.cart-count::before { content: "("; }
.cart-count::after { content: ")"; }

main { flex: 1; width: 100%; max-width: var(--wide); margin: 0 auto; padding: 0 var(--gutter); }

.site-footer {
  margin-top: 7rem;
  border-top: 1px solid var(--hair);
  padding: 2rem var(--gutter) 3.5rem;
  max-width: var(--wide);
  margin-inline: auto;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.5rem;
  align-items: baseline;
  justify-content: space-between;
  color: var(--ash);
}
.footer-brand { margin: 0; font-family: var(--display); font-size: 0.9375rem; letter-spacing: 0.06em; color: var(--ink); }
.footer-nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.footer-nav a { color: var(--ash); text-decoration: none; padding-block: 0.25rem; }
.footer-nav a:hover { color: var(--ink); text-decoration: underline; }
.footer-fine { margin: 0; font-size: 0.8125rem; letter-spacing: 0; text-transform: none; flex-basis: 100%; }

/* --- Type ---------------------------------------------------------------- */

/* Balanced, so no heading ends on one word — "went through" hung alone under
   the stalled thank-you page, and "A$120" under the banner at 375px. */
h1, h2, h3, .banner { text-wrap: balance; }
h1, h2, h3 { font-weight: 400; margin: 0; }

.page-title {
  font-family: var(--display);
  font-size: clamp(1.75rem, 5vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  margin: 4rem 0 0.5rem;
}
.page-note { margin: 0 0 3.5rem; color: var(--ash); font-size: 0.875rem; }

.prose { max-width: var(--measure); }
.prose h1 { font-family: var(--display); font-size: clamp(1.6rem, 4.5vw, 2.125rem); line-height: 1.2; margin: 4rem 0 1.5rem; }
.prose h2 { font-size: 1rem; margin: 2.5rem 0 0.5rem; letter-spacing: 0.01em; }
.prose p, .prose li { color: #2e3033; }
.prose p { margin: 0 0 1.25rem; }
.prose ul { padding-left: 1.1rem; }
.prose code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 0.85em; }
.prose a { color: var(--indigo); }

.muted { color: var(--ash); }
.fine { color: var(--ash); }

.notice, .error {
  padding: 0.9rem 1.1rem;
  margin: 1.5rem 0;
  font-size: 0.875rem;
  border-left: 2px solid var(--ink);
  background: var(--plate);
}
.error { border-left-color: #9d2f1e; color: #7d2416; }
.empty { color: var(--ash); margin: 3rem 0; }

/* --- Buttons ------------------------------------------------------------- */

.button {
  display: inline-block;
  font-family: var(--text);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  padding: 1rem 2rem;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.button:hover { background: var(--ink); color: var(--paper); }
.button-primary { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.button-primary:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.button-big { width: 100%; }

/* --- Photographic plates ------------------------------------------------- */

/* Portrait, on true white, with the object contained rather than cropped —
   a piece in a case, not a tile in a catalogue. */
.plate {
  background: var(--plate);
  border: 1px solid var(--hair);
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: 1.25rem;
  transition: border-color 160ms ease;
}
.plate img { width: 100%; height: 100%; object-fit: contain; }
/* No photograph yet. Empty, the plate read as an image that failed to load;
   it now says so in the label voice. Too small to say it in the cart, where
   the line's title beside it names the piece. */
.plate-empty { background: var(--plate); }
.plate-empty-note {
  color: var(--ash);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  text-align: center;
  line-height: 1.6;
}

/* --- The shop grid ------------------------------------------------------- */

/* Offset alternate items. One-off objects laid out on a cloth; a perfectly
   even grid would say "mass produced", which is the one thing this shop is
   not. Collapses to a single true column on a phone. */
.grid {
  list-style: none;
  margin: 0;
  padding: 0 0 4rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem 2rem;
}
@media (min-width: 40rem) {
  .grid { grid-template-columns: repeat(2, 1fr); gap: 4rem 2rem; padding-bottom: 7.5rem; }
  .grid > li:nth-child(2n) { transform: translateY(3.5rem); }
}
@media (min-width: 60rem) {
  .grid { grid-template-columns: repeat(3, 1fr); }
  .grid > li:nth-child(2n) { transform: none; }
  .grid > li:nth-child(3n - 1) { transform: translateY(3.5rem); }
}

.card a { text-decoration: none; color: inherit; display: block; }
.card a:hover .plate { border-color: var(--ink); }
.card-body { border-top: 1px solid var(--hair); margin-top: 1rem; padding-top: 0.75rem; }
.card-title { font-size: 0.9375rem; line-height: 1.4; margin: 0; }
.card-price { margin: 0.15rem 0 0; color: var(--ash); font-size: 0.875rem; font-variant-numeric: tabular-nums; }

/* The signature: the availability of each piece, stated as a museum label.
   It is the truest fact about this shop and the one its whole architecture
   is built around. */
.card-stock { margin: 0.6rem 0 0; color: var(--ink); }
.card-stock[data-sold] { color: var(--ash); }
.card-sold .plate img { opacity: 0.42; }

/* --- Product ------------------------------------------------------------- */

.product { display: grid; gap: 2.5rem; margin: 3rem 0 5rem; }
@media (min-width: 52rem) {
  /* Both columns bounded. Letting the plate take 1fr made it tower over a
     short description and opened a dead quarter under the text. */
  .product {
    grid-template-columns: minmax(0, 26rem) minmax(0, 21rem);
    justify-content: space-between;
    gap: 4rem;
    align-items: start;
  }
}

.gallery-rest { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); gap: 0.75rem; padding: 0; margin: 0.75rem 0 0; }
.gallery-rest .plate { aspect-ratio: 1; padding: 0.5rem; }

.product-title { font-family: var(--display); font-size: clamp(1.5rem, 4vw, 2rem); line-height: 1.2; margin: 0 0 0.75rem; }
.price { font-size: 1rem; margin: 0 0 2rem; font-variant-numeric: tabular-nums; }

.specimen {
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  padding: 0.85rem 0;
  margin: 2rem 0;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  color: var(--ash);
}
.specimen strong { color: var(--ink); font-weight: 400; }

.add-form { margin: 0 0 1.5rem; }
.sold-note { color: var(--ash); font-size: 0.875rem; }
.product-detail .prose { max-width: none; }
.product-detail .prose p { font-size: 0.9375rem; }

.materials { margin: 2rem 0 0; }
.materials dt { color: var(--ash); margin-bottom: 0.35rem; }
.materials dd { margin: 0; font-size: 0.9375rem; }
.ship-note { margin-top: 2.5rem; font-size: 0.8125rem; }
.ship-note a { display: inline-block; padding-block: 0.35rem; }

/* --- Home ---------------------------------------------------------------- */

/* No headline, no hero button. The most characteristic thing about this shop
   is the objects themselves, so the front window is one piece, presented. */
.window { display: grid; gap: 2rem; margin: 3.5rem 0 6rem; }
@media (min-width: 52rem) {
  .window { grid-template-columns: minmax(0, 1fr) minmax(0, 17rem); gap: 4rem; align-items: end; }
}
.window > a { display: block; max-width: 30rem; }
.window .plate { aspect-ratio: 4 / 5; }
.window-text { padding-bottom: 0.5rem; }
.window-text { max-width: 22rem; }
.window-eyebrow { color: var(--ash); margin: 0 0 1rem; }
.window-title { font-family: var(--display); font-size: clamp(1.75rem, 4.5vw, 2.25rem); line-height: 1.2; margin: 0 0 0.5rem; }
.window-title a { color: inherit; text-decoration: none; }
.window-title a:hover { text-decoration: underline; }
.window-price { color: var(--ash); margin: 0; font-variant-numeric: tabular-nums; }
/* The promise under the price, as on every product page. */
.window .lead-time { margin: 0.35rem 0 1.5rem; }
.window-blurb { margin: 0 0 2rem; color: #2e3033; }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--hair);
  padding-bottom: 0.75rem;
  margin-bottom: 2.5rem;
}
.section-head h1, .section-head h2 { font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; color: var(--ink); }
.section-head a { padding-block: 0.25rem; color: var(--ash); text-decoration: none; font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; }
.section-head a:hover { color: var(--ink); }

/* --- Cart ---------------------------------------------------------------- */

.cart { max-width: 44rem; margin-bottom: 5rem; }
.cart > h1 {
  font-family: var(--display);
  font-size: clamp(1.6rem, 4.5vw, 2.125rem);
  line-height: 1.2;
  margin: 4rem 0 1.5rem;
}

.cart-table { width: 100%; border-collapse: collapse; margin: 0 0 2rem; }
.cart-table th, .cart-table td { text-align: left; padding: 1.25rem 0.5rem; border-bottom: 1px solid var(--hair); font-weight: 400; vertical-align: top; }
.cart-table thead th { padding-block: 0 0.75rem; color: var(--ash); }
.cart-table .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; width: 7rem; }
.cart-table tfoot th { font-size: 0.875rem; }
.cart-table tfoot tr:last-child th, .cart-table tfoot tr:last-child td { border-bottom: 0; }

/* Quantity lives inside the item cell, beside the thing it counts. As its
   own column it could not hold three 44px targets on a 390px phone, and the
   title overlapped the buttons. Two columns fit anywhere. */
.cart-item { display: flex; gap: 1rem; align-items: flex-start; }
.cart-item .plate { width: 4.5rem; flex: none; aspect-ratio: 4/5; padding: 0.35rem; }
.cart-item-text { display: flex; flex-direction: column; align-items: flex-start; gap: 0.15rem; min-width: 0; }
/* On a phone the plates sit above the words. Beside them, two plates and a
   7rem price column left a mixed pair's title 77px wide: eight lines, a row
   419px tall, "+" wrapped under "−", and 28px of sideways scroll at 320. */
@media (max-width: 30rem) {
  .cart-item { flex-direction: column; gap: 0.75rem; }
  .cart-table .num { width: auto; padding-left: 0.75rem; }
}
.cart-item a { color: var(--ink); text-decoration: none; }
.cart-item a:hover { text-decoration: underline; }
.cart-item small { color: var(--ash); font-size: 0.8125rem; line-height: 1.5; }

.cart-qty { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.75rem; flex-wrap: wrap; }
.qty-step {
  display: inline-grid; place-items: center;
  width: 2.75rem; height: 2.75rem;
  border: 1px solid var(--hair); text-decoration: none; color: var(--ink);
  transition: border-color 160ms ease;
}
.qty-step:hover { border-color: var(--ink); }
/* At the cap. Surface, not opacity — dimmed, the "+" measured 1.91:1. */
.qty-step.is-disabled { background: #ecebe6; color: var(--ash); pointer-events: none; }
.qty-value { min-width: 1.75rem; text-align: center; font-variant-numeric: tabular-nums; }
.qty-remove {
  margin-left: 0.5rem; padding-block: 0.35rem; color: var(--ash);
  font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
  text-decoration: none;
}
.qty-remove:hover { color: var(--ink); text-decoration: underline; }
/* A line whose parts have run out. State goes in the surface, never in
   opacity: dimming the row took its text to 3.1:1 and the accessibility gate
   failed it — the same mistake the bench has a rule about. The words keep
   their contrast; the price is struck through, because it is genuinely not
   being charged. */
.line-sold > * { background: #ecebe6; }
.line-sold .num { text-decoration: line-through; color: var(--ash); }

.cart-actions { margin: 2rem 0 0; max-width: 22rem; }
.cart-actions .fine { display: block; margin-top: 1rem; text-transform: none; letter-spacing: 0; font-size: 0.8125rem; line-height: 1.6; }
.cart-back { margin-top: 3rem; }
.cart-back a { display: inline-block; padding-block: 0.4rem; color: var(--ash); font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; text-decoration: none; }
.cart-back a:hover { color: var(--ink); }

.thanks { max-width: var(--measure); padding-bottom: 5rem; }
.order-no { color: var(--ash); margin: -0.75rem 0 1.5rem; font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; }

/* --- Forms --------------------------------------------------------------- */

.form { max-width: var(--measure); }
.field { margin: 0 0 1.5rem; display: flex; flex-direction: column; gap: 0.5rem; }
.field label { font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; color: var(--ash); }
.field small { color: var(--ash); font-size: 0.8125rem; }

input[type="text"], input[type="email"], input[type="number"], textarea, select {
  font: inherit;
  font-size: 0.9375rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--hair);
  background: var(--plate);
  color: var(--ink);
  width: 100%;
  border-radius: 0;
}
input:hover, textarea:hover { border-color: #c4c4bd; }
input:focus, textarea:focus { border-color: var(--indigo); outline-offset: 1px; }
textarea { resize: vertical; line-height: 1.65; }

.rates { border-collapse: collapse; width: 100%; max-width: var(--measure); margin: 1.5rem 0 2rem; }
.rates th, .rates td { text-align: left; padding: 0.85rem 0.5rem; border-bottom: 1px solid var(--hair); font-weight: 400; }
.rates .num { text-align: right; font-variant-numeric: tabular-nums; }
.rates thead th { color: var(--ash); padding-block: 0 0.6rem; }
.rates tbody th { font-weight: 400; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* The grid offset is deliberately NOT flattened here. prefers-reduced-motion
   is about things that move; a static translateY never animates, so cancelling
   it would be answering a question nobody asked. An earlier version did cancel
   it, keyed on nth-child(even) — which stopped matching when the offset moved
   to the column (3n - 1) and so applied at one breakpoint and not the other.
   Layout that differs by viewport under a motion preference is worse than
   either choice made consistently. */

/* --- Prototype notice ---------------------------------------------------- */

/* Only rendered on a demo deployment (DEMO=true). It is not a setting and
   cannot be switched off in the admin, because a notice saying "none of this
   is real" is not something a demo should be able to hide. */
.demo-bar {
  margin: 0;
  padding: 0.75rem var(--gutter);
  background: #3d2f12;
  color: #f7e6bd;
  text-align: center;
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  line-height: 1.5;
}

/* --- Made to order ------------------------------------------------------- */

/* The unit qualifier next to a price. A listing is one charm and the price is
   one earring, so "each" is load-bearing rather than decorative — leaving it
   off reads as half the price of a pair. */
.price-unit,
.card-unit { color: var(--ash); }
.card-unit { font-size: var(--label-size); letter-spacing: var(--label-track); text-transform: uppercase; }
.price-unit { font-size: 0.8125rem; letter-spacing: 0; }

/* The one sentence that stops a customer expecting tomorrow. It sits with the
   availability label, in the same voice, because it is the other half of the
   same fact: what there is, and when it arrives. */
.lead-time {
  margin: 0.5rem 0 2rem;
  color: var(--ash);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  line-height: 1.6;
}

/* The configurator. The vitrine is still and this is a tool, which is exactly
   why it lives on the product page and not on the front door: one click in,
   where someone has already decided to look properly. It borrows the form
   vocabulary rather than inventing a second one — hairlines, ink on hover,
   the same 160ms and nothing else moving. */
.configure { margin: 0 0 2rem; max-width: 26rem; }
.configure-group { border: 0; padding: 0; margin: 0 0 1.5rem; }
.configure-group legend {
  padding: 0;
  color: var(--ash);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
}

.choice-row { display: flex; gap: 0.75rem; margin-top: 0.75rem; }
.choice-col { display: grid; gap: 0.5rem; margin-top: 0.75rem; }

/* 44px targets, because this is the one place on the storefront where somebody
   is making a series of small decisions in a row. */
.choice {
  display: flex; align-items: flex-start; gap: 0.65rem;
  border: 1px solid var(--hair); padding: 0.7rem 0.9rem;
  min-height: 2.75rem; cursor: pointer;
  transition: border-color 160ms ease;
}
.choice-row .choice { flex: 1; align-items: center; }
.choice:hover { border-color: var(--ink); }
.choice input { margin: 0.3rem 0 0; accent-color: var(--indigo); flex: none; }
.choice-row .choice input { margin: 0; }
.choice span { display: block; min-width: 0; }
.choice small { display: block; color: var(--ash); font-size: 0.8125rem; line-height: 1.5; }
.choice:has(input:checked) { border-color: var(--ink); }
/* A choice the shop cannot make. Surface and cursor, never opacity — the words
   have to keep their contrast, same as the cart's struck-out line. */
.choice:has(input:disabled) { background: #ecebe6; cursor: default; }
.choice:has(input:disabled):hover { border-color: var(--hair); }
.choice:has(input:focus-visible) { outline: 2px solid var(--indigo); outline-offset: 2px; }

.configure-other { margin: 1rem 0 0; }
.configure-other[hidden] { display: none; }

.configure-total {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin: 0 0 1.25rem;
  padding-top: 0.9rem; border-top: 1px solid var(--hair);
}
.configure-total .label { color: var(--ash); }
.configure-total strong { font-weight: 400; font-size: 1.125rem; font-variant-numeric: tabular-nums; }

/* A mixed pair has never been photographed — it does not exist yet — so the
   cart shows its two charms side by side. The only place on the storefront
   where two plates sit together, and it is the honest picture of what is about
   to be made. */
.cart-plates { display: flex; gap: 0.35rem; flex: none; }
.cart-plates-pair .plate { width: 3.25rem; }
