/* Lara Craft — warm, simple, readable on a phone at a market stall. */

:root {
  --ink: #2f2a26;
  --ink-soft: #6b625b;
  --paper: #fdfaf6;
  --card: #fff;
  --line: #e6ded4;
  --accent: #a8543f;
  --accent-soft: #f6e9e3;
  --ok: #2f6b46;
  --warn: #8a5a12;
  --warn-soft: #fdf3e0;
  --radius: 12px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.6 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: var(--paper);
}

/* Replacing the picture? Bump ?v= on both references below. This stylesheet is
   cache-busted by content hash automatically, but URLs *inside* it aren't, and
   /static/ is cached for a week — without the bump, returning visitors keep
   seeing the old picture.

   Lara's drawing behind the whole shop, under a wash so text stays readable.
   A fixed pseudo-element rather than `background-attachment: fixed`, which
   iOS Safari renders badly. The wash is the same colour as --paper, so if the
   image ever fails to load the page just looks normal rather than broken. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(rgba(253, 250, 246, .85), rgba(253, 250, 246, .85)),
    url("background.webp?v=2") center / cover no-repeat;
}

main {
  max-width: 62rem;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

h1 { font-size: 1.75rem; margin: 0 0 .5rem; letter-spacing: -.01em; }
h2 { font-size: 1.2rem; margin: 2rem 0 .75rem; }
a { color: var(--accent); }
img { max-width: 100%; display: block; }

.lede { color: var(--ink-soft); margin: 0 0 2rem; }
.hint, .each, .optional, .order-meta { color: var(--ink-soft); font-size: .875rem; }
.empty { color: var(--ink-soft); padding: 2rem 0; }
.right { text-align: right; }
.narrow { max-width: 38rem; }
.centred { text-align: center; padding: 3rem 0; }
.back { margin: 0 0 1rem; font-size: .9rem; }

/* --- header / footer --- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--line);
  /* Slightly see-through, so the drawing carries up behind the shop name
     instead of being cut off by a solid bar. */
  background: rgba(255, 255, 255, .72);
  backdrop-filter: blur(10px);
}
/* Rainbow stripe along the bottom of the header. The red and green are
   sampled from Lara's drawing; the rest complete the arc. */
.site-header { position: relative; }
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;                 /* sit on top of the 1px border, not below it */
  height: 5px;
  background: linear-gradient(90deg,
    #c93a26 0%, #e08a2e 20%, #e8c33a 40%,
    #4f9d1f 60%, #3f86b5 80%, #7d5ba6 100%);
}

.brand {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -.015em;
  text-decoration: none;
  color: var(--ink);
}
.brand-mark {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(47, 42, 38, .22);
  flex: 0 0 auto;
}
.brand-name { line-height: 1.1; }
.site-header nav { display: flex; gap: 1.25rem; align-items: center; }
.site-header nav a { text-decoration: none; font-size: .95rem; }
.pill {
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  padding: 0 .45rem;
  font-size: .8rem;
}
.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: center;
  padding: 1.25rem;
  border-top: 1px solid var(--line);
  font-size: .85rem;
}
.inline { display: inline; }
.linkish {
  background: none;
  border: 0;
  padding: 0;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  text-decoration: underline;
}

/* --- flashes --- */

.flashes { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: .5rem; }
.flash { padding: .6rem .85rem; border-radius: var(--radius); font-size: .925rem; }
.flash-ok { background: var(--accent-soft); color: var(--accent); }
.flash-warn { background: var(--warn-soft); color: var(--warn); }

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

.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.card a { text-decoration: none; color: inherit; display: block; }
/* contain, not cover: a photo of several colours side by side is much wider
   than the card, and cropping it to fill would cut half the colours off. The
   tinted backing makes the letterboxing look deliberate rather than broken. */
.card img {
  aspect-ratio: 4 / 3;
  object-fit: contain;
  width: 100%;
  background: var(--paper);
  padding: .4rem;
}
.card h2 { font-size: 1rem; margin: .85rem .85rem .25rem; }
.card .price { margin: 0 .85rem 1rem; font-weight: 600; }
.card.sold-out img { filter: grayscale(1); opacity: .55; }

/* --- colour swatches --- */

.swatch-row {
  display: flex;
  align-items: center;
  gap: .3rem;
  margin: 0 .85rem 1rem;
  flex-wrap: wrap;
}
/* Shop card: small photo tiles, one per colour. */
.swatch {
  /* Large enough for the colour to actually read. The photos are shot on
     white, so at thumbnail size most of a smaller tile is background. */
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 5px;
  border: 1px solid var(--line);
  overflow: hidden;
  background: var(--paper);
  display: block;
  flex: 0 0 auto;
}
.swatch img { width: 100%; height: 100%; object-fit: cover; }
.swatch-fill { display: block; width: 100%; height: 100%; background: var(--accent-soft); }
.swatch-gone { opacity: .35; }
.swatch-count { font-size: .8rem; color: var(--ink-soft); }

/* Product page: photo, colour name underneath. The photo is the swatch —
   for handmade yarn the real thing beats any colour approximation. */
.picker { margin: 1.25rem 0; }
.picker-label { margin: 0 0 .5rem; font-size: .925rem; }
.swatches {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  margin: 0;
  padding: 0;
}
.swatch-btn {
  display: block;
  width: 4.5rem;
  padding: .25rem .25rem .35rem;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}
.swatch-btn img,
.swatch-btn .swatch-fill {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 6px;
  background: var(--paper);
}
.swatch-name {
  display: block;
  margin-top: .25rem;
  font-size: .75rem;
  line-height: 1.25;
  color: var(--ink-soft);
}
.swatch-sold {
  display: block;
  font-size: .65rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--warn);
}
.swatch-btn:hover { border-color: var(--ink-soft); }
.swatch-btn.is-chosen { border-color: var(--accent); }
.swatch-btn.is-chosen .swatch-name { color: var(--ink); font-weight: 600; }
/* Sold-out colours stay clickable — seeing what she made is half the appeal,
   and the page says plainly that it's gone. */
.swatch-btn.is-gone img { filter: grayscale(1); opacity: .55; }

/* --- admin variant rows --- */

.variants-heading { font-size: .95rem; margin: 1.25rem 0 .5rem; }
.variant-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem;
  padding: .5rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: .4rem;
}
.variant-row input { margin-top: 0; width: auto; flex: 1 1 7rem; min-width: 5rem; }
.variant-row .swatch-input,
.variant-row .stock-input,
.variant-row .price-input { flex: 0 0 5.5rem; }
.variant-row .choice { flex: 0 0 auto; margin: 0; }
.variant-new { border-style: dashed; }
.variant-thumb { width: 2.5rem; height: 2.5rem; border-radius: 6px;
                 object-fit: contain; background: var(--paper); }
.variant-delete { margin: -.2rem 0 .6rem; }
.variant-delete button { font-size: .8rem; padding: .25rem .6rem; color: var(--ink-soft); }

.stall-variant { font-size: .8rem; color: var(--accent); font-weight: 500; }

.no-photo {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 2.5rem;
}
.no-photo.big { aspect-ratio: 1; font-size: 5rem; border-radius: var(--radius); }

.tag {
  display: inline-block;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 999px;
  padding: .1rem .6rem;
  font-size: .75rem;
  font-weight: 500;
  vertical-align: middle;
}
.tag-quiet { background: var(--line); color: var(--ink-soft); }

/* --- product --- */

.product { display: grid; gap: 2rem; grid-template-columns: 1fr; }
@media (min-width: 44rem) { .product { grid-template-columns: 1fr 1fr; } }
.product img { border-radius: var(--radius); }
.price.big { font-size: 1.5rem; margin: 0 0 1rem; }
.description { white-space: pre-line; }
.stock { color: var(--warn); font-size: .9rem; }

/* --- tables --- */

.lines { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.lines td, .lines th { padding: .7rem .5rem; border-bottom: 1px solid var(--line); text-align: left; }
.lines tfoot th { border-bottom: 0; font-size: 1.05rem; }
.lines .each { display: block; }
.lines input[type=number] { width: 4.5rem; }
.summary { max-width: 30rem; }

/* --- forms --- */

form.stacked { display: grid; gap: 1rem; max-width: 32rem; }
label { display: block; font-size: .925rem; font-weight: 500; }
input, textarea, select {
  font: inherit;
  width: 100%;
  margin-top: .3rem;
  padding: .55rem .7rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: inherit;
}
input[type=radio], input[type=checkbox] { width: auto; margin: 0 .5rem 0 0; }
input[type=file] { padding: .4rem; }
textarea { resize: vertical; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem; }
legend { font-weight: 500; font-size: .925rem; padding: 0 .35rem; }
.choice { display: flex; align-items: flex-start; gap: .1rem; font-weight: 400; margin: .5rem 0; }
.actions { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }

button, .button {
  font: inherit;
  cursor: pointer;
  display: inline-block;
  padding: .6rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card);
  color: var(--ink);
  text-decoration: none;
}
button:hover, .button:hover { border-color: var(--ink-soft); }
button.primary, .button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
button.primary:hover, .button.primary:hover { filter: brightness(1.08); }
button.big { padding: .8rem 1.4rem; font-size: 1.05rem; }
button:disabled { opacity: .45; cursor: not-allowed; }

.boxed {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1rem;
  max-width: none;
}
.row-form { display: flex; gap: 1.25rem; align-items: flex-start; flex-wrap: wrap; }
.row-fields { display: grid; gap: .75rem; flex: 1; min-width: 16rem; }
.thumb { width: 7rem; border-radius: 8px; aspect-ratio: 1; object-fit: contain;
         background: var(--paper); }

/* --- orders --- */

.order.done { opacity: .6; }
.order-head { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.order-head .right { margin-left: auto; font-weight: 600; }
.order-items { margin: .6rem 0; padding-left: 1.2rem; }
.order-meta { margin: .2rem 0; }

/* --- stall mode: big targets, thumb-reachable action bar --- */

.stall-title { margin-bottom: .25rem; }
.stall-grid {
  list-style: none;
  margin: 1.25rem 0 6rem;
  padding: 0;
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
}
.stall-item {
  width: 100%;
  min-height: 5.5rem;
  display: grid;
  gap: .2rem;
  align-content: center;
  text-align: center;
  padding: .75rem .5rem;
  position: relative;
}
.stall-item.picked { background: var(--accent-soft); border-color: var(--accent); }
.stall-name { font-weight: 500; line-height: 1.3; }
.stall-price { color: var(--ink-soft); font-size: .875rem; }
.stall-qty {
  position: absolute;
  top: -.5rem;
  right: -.5rem;
  min-width: 1.6rem;
  height: 1.6rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: .85rem;
  font-weight: 600;
}

.stall-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  gap: .75rem;
  align-items: center;
  padding: .85rem 1.25rem;
  padding-bottom: max(.85rem, env(safe-area-inset-bottom));
  background: var(--card);
  border-top: 1px solid var(--line);
}
.stall-bar span { font-size: 1.35rem; font-weight: 600; margin-right: auto; }

dialog {
  border: 0;
  border-radius: var(--radius);
  padding: 1.75rem;
  max-width: 24rem;
  text-align: center;
  background: var(--card);
  color: var(--ink);
}
dialog::backdrop { background: rgba(47, 42, 38, .6); }
dialog h2 { margin-top: 0; }
#qr { margin: 0 auto 1rem; max-width: 15rem; }
#qr svg { width: 100%; height: auto; display: block; }
.waiting { color: var(--ink-soft); font-size: .9rem; }
.tick { font-size: 3.5rem; color: var(--ok); margin: 0; line-height: 1; }

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f0e9e2;
    --ink-soft: #a99e94;
    --paper: #1d1a18;
    --card: #272320;
    --line: #3d3733;
    --accent: #e0937c;
    --accent-soft: #3a2a24;
    --warn: #e0b46a;
    --warn-soft: #3a2f1c;
    --ok: #7fc99a;
  }
  button.primary, .button.primary { color: #1d1a18; }
  .card.sold-out img { opacity: .4; }

  /* The drawing is bright, so it needs a heavier wash to sit under pale text. */
  body::before {
    background:
      linear-gradient(rgba(29, 26, 24, .90), rgba(29, 26, 24, .90)),
      url("background.webp?v=2") center / cover no-repeat;
  }
  .site-header { background: rgba(39, 35, 32, .72); }
}

/* Readers who've asked their system for higher contrast get the plain paper —
   a picture behind text is exactly what that setting is meant to suppress. */
@media (prefers-contrast: more) {
  body::before { background: var(--paper); }
  .site-header { background: var(--card); backdrop-filter: none; }
}

.needs-name {
  flex: 1 1 100%;
  font-size: .8rem;
  color: var(--warn);
}
