/* MyRewardz Retail storefront.
 *
 * Hand-written and served straight off disk -- there is deliberately no asset pipeline
 * here, so a deploy stays a git pull with no npm step. This file replaced the inline
 * <style> block that used to live in layouts/app.blade.php; it is linked with a filemtime
 * cache-buster so a changed stylesheet is picked up without a hard refresh.
 *
 * The palette and the class vocabulary (.wrap, .grid, .card, .thumb, .btn, .flash, .field)
 * are carried over unchanged from that block, so every view kept rendering while the new
 * pages were added.
 */

:root {
    --ink: #16202a; --muted: #5c6b7a; --line: #e2e8f0;
    --bg: #f7f9fb; --panel: #ffffff; --accent: #0b6b53; --accent-ink: #ffffff;
    --accent-dark: #085140; --accent-wash: #e8f2ee;
    --danger: #a3241c; --danger-bg: #fdeceb; --ok: #12694f; --ok-bg: #e8f5f0;
    --shadow: 0 1px 2px rgba(22, 32, 42, .04), 0 10px 28px -20px rgba(22, 32, 42, .3);
    --radius: 10px;
}

* { box-sizing: border-box; }

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

a { color: var(--accent); }
img { max-width: 100%; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }

/* ---------- announcement bar ---------- */
.announce {
    background: var(--accent-dark); color: #dbeae4;
    font-size: .8rem; letter-spacing: .01em;
}
.announce .wrap {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 34px;
    padding-top: 9px; padding-bottom: 9px; text-align: center;
}

/* ---------- header ---------- */
header.site { background: var(--panel); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10; }
header.site .bar { display: flex; align-items: center; gap: 20px; height: 68px; }
.brand {
    display: flex; align-items: center; gap: 10px;
    font-weight: 700; font-size: 1.15rem; text-decoration: none; color: var(--ink);
    white-space: nowrap;
}
/* Sized by height so the intrinsic width/height on the <img> still reserves the right
   box before the PNG loads and the bar does not jump. */
.brand-mark { height: 38px; width: auto; display: block; }
.brand-name span { color: var(--accent); }
header.site nav.util { margin-left: auto; display: flex; align-items: center; gap: 18px; font-size: .95rem; }
header.site nav.util a { text-decoration: none; }
header.site nav.util form { margin: 0; }

/* ---------- header search ---------- */
/* The dropdown is positioned against this, and must clear the category nav below -- the
   header is sticky at z-index 10, so the panel sits above it at 11. */
.search { position: relative; display: flex; gap: 6px; margin-left: 26px; flex: 0 1 340px; }
.search input[type="search"] {
    flex: 1; min-width: 0; padding: 8px 12px; background: var(--bg);
    -webkit-appearance: none; appearance: none;
}
.search input[type="search"]:focus { background: var(--panel); }
.search button {
    background: transparent; border-color: var(--line); color: var(--muted);
    cursor: pointer; padding: 8px 13px; font-size: .9rem;
}
.search button:hover { border-color: var(--accent); color: var(--accent); }

.search-suggestions {
    position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 11;
    list-style: none; margin: 0; padding: 6px;
    background: var(--panel); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow);
    max-height: 60vh; overflow-y: auto;
}
.search-suggestions[hidden] { display: none; }
.search-suggestions li a {
    display: flex; flex-direction: column; gap: 2px;
    padding: 9px 11px; border-radius: 7px; text-decoration: none; color: var(--ink);
}
.search-suggestions li a:hover,
.search-suggestions li.on a { background: var(--accent-wash); }
.search-suggestions .sg-name { font-size: .93rem; font-weight: 600; }
.search-suggestions .sg-meta { font-size: .79rem; color: var(--muted); }
.search-suggestions .sg-all { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 4px; }
.search-suggestions .sg-all a { font-size: .85rem; color: var(--accent); font-weight: 600; }

/* Category nav. Scrolls sideways on a narrow screen rather than wrapping into a second
   row that would push the page content below the fold. */
nav.cats { border-top: 1px solid var(--line); }
nav.cats .wrap { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: thin; }
nav.cats a {
    display: block; padding: 12px 14px; text-decoration: none; color: var(--ink);
    font-size: .93rem; font-weight: 500; white-space: nowrap;
    border-bottom: 2px solid transparent;
}
nav.cats a:hover { color: var(--accent); }
nav.cats a.on { color: var(--accent); border-bottom-color: var(--accent); }
nav.cats a.all { color: var(--muted); }

main { padding: 32px 0 64px; }

/* ---------- type ---------- */
h1 { font-size: 1.7rem; margin: 0 0 6px; letter-spacing: -.01em; }
h2 { font-size: 1.25rem; margin: 0; letter-spacing: -.01em; }
.lede { color: var(--muted); margin: 0 0 24px; }
.muted { color: var(--muted); }

.crumbs { font-size: .85rem; color: var(--muted); margin-bottom: 14px; }
.crumbs a { text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }

.sec-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 16px; margin: 40px 0 16px; flex-wrap: wrap;
}
.sec-head:first-child { margin-top: 0; }
.sec-head a { font-size: .9rem; text-decoration: none; white-space: nowrap; }
.sec-head a:hover { text-decoration: underline; }

/* ---------- hero ---------- */
.hero {
    background: linear-gradient(105deg, var(--accent-wash) 0%, #f4f8f6 60%, var(--bg) 100%);
    border: 1px solid var(--line); border-radius: 16px;
    padding: 52px 44px; margin-bottom: 8px;
}
.hero h1 { font-size: clamp(1.9rem, 4.4vw, 2.9rem); max-width: 15ch; line-height: 1.12; }
.hero h1 em { font-style: normal; color: var(--accent); }
.hero p { color: var(--muted); max-width: 46ch; margin: 14px 0 26px; font-size: 1.05rem; }
.hero .actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- trust strip ---------- */
.trust {
    display: grid; gap: 14px; margin-top: 18px;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.trust div {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 16px 18px;
}
.trust strong { display: block; font-size: .93rem; }
.trust span { color: var(--muted); font-size: .84rem; }

/* ---------- category tiles ---------- */
.cat-tiles { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }
.cat-tile {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 16px; text-decoration: none; color: var(--ink); display: block;
    transition: border-color .15s, box-shadow .15s, transform .15s;
}
.cat-tile:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); }
.cat-tile .thumb { aspect-ratio: 1 / 1; margin-bottom: 12px; }
.cat-tile strong { display: block; font-size: .96rem; }
.cat-tile span { color: var(--muted); font-size: .82rem; }

/* ---------- product grid ---------- */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); }
.card {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 18px; display: flex; flex-direction: column;
    transition: border-color .15s, box-shadow .15s;
}
.card:hover { border-color: #cdd8e2; box-shadow: var(--shadow); }
.card h3 { margin: 0 0 4px; font-size: 1rem; line-height: 1.35; }
.card h3 a { text-decoration: none; color: inherit; }
.card h3 a:hover { color: var(--accent); }
.card .eyebrow {
    font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
    color: var(--muted); margin-bottom: 6px;
}
.card .eyebrow a { color: inherit; text-decoration: none; }
.card .eyebrow a:hover { color: var(--accent); }

/* Fixed box with object-fit:contain, because product photos arrive at whatever aspect
   ratio the supplier shot them at and must not stretch or crop the grid. */
.thumb {
    display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: contain;
    background: #f1f4f7; border-radius: 7px; margin-bottom: 12px;
}
/* The placeholder sits inside the card's image link, so it would otherwise inherit the
   link underline and render "No image" as if it were clickable text. */
a.thumb-link { display: block; text-decoration: none; }
/* IMAGE_URL is null for most products and that is the normal state, not an error --
   the API returns a URL only when the file exists on disk. */
.thumb-empty {
    display: flex; align-items: center; justify-content: center;
    color: var(--muted); font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
}

.price { font-size: 1.25rem; font-weight: 700; margin: 8px 0 2px; }
.stock { color: var(--muted); font-size: .85rem; margin-bottom: 14px; }
.stock.out { color: var(--danger); }
.card form { margin-top: auto; display: flex; gap: 8px; }

/* ---------- product detail ---------- */
.product { display: grid; gap: 36px; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
.gallery-panel {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px;
}

/* ---------- gallery ---------- */
/* Every frame is in the DOM and CSS hides the inactive ones, so with no JavaScript the
   first image simply shows and the thumbnails are still links to the full-size files.

   The fixed box lives HERE, on the container, not on the images. Product photos arrive at
   whatever aspect ratio the supplier shot them at -- 900x700 beside 555x351 -- and the box
   must not resize as the shopper flips between them.

   The frames are absolutely positioned so the container's height comes from its own
   aspect-ratio alone and never from whichever image happens to be showing. The images then
   set height:100% explicitly: they carry width/height attributes (which describe the real
   pixel dimensions and stop the box shifting while the first one loads), and those
   attributes are presentational hints that would otherwise supply the used height and make
   aspect-ratio moot -- which is exactly how this resized before. */
.gallery-main {
    position: relative; aspect-ratio: 1 / 1;
    background: #fff; border-radius: 7px; overflow: hidden;
}
.gallery-frame { position: absolute; inset: 0; display: none; }
.gallery-frame.on { display: block; }
.gallery-frame img {
    display: block; width: 100%; height: 100%; object-fit: contain;
}
.gallery-main-empty { aspect-ratio: 1 / 1; margin: 0; background: #f1f4f7; }

.gallery-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 38px; height: 38px; padding: 0; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem; color: var(--ink); cursor: pointer;
    background: rgba(255, 255, 255, .92); border: 1px solid var(--line); border-radius: 50%;
    box-shadow: var(--shadow); opacity: 0; transition: opacity .15s, border-color .15s;
}
.gallery-main:hover .gallery-nav,
.gallery-nav:focus-visible { opacity: 1; }
.gallery-nav:hover { border-color: var(--accent); color: var(--accent); }
.gallery-nav.prev { left: 4px; }
.gallery-nav.next { right: 4px; }
/* Touch has no hover, so the arrows would never appear. */
@media (hover: none) { .gallery-nav { opacity: 1; } }

.gallery-counter {
    position: absolute; right: 8px; bottom: 8px;
    background: rgba(22, 32, 42, .72); color: #fff;
    font-size: .74rem; padding: 3px 9px; border-radius: 100px;
    font-variant-numeric: tabular-nums;
}

.gallery-thumbs {
    list-style: none; margin: 14px 0 0; padding: 0;
    display: flex; gap: 10px; flex-wrap: wrap;
}
.gallery-thumb {
    padding: 0; width: 64px; height: 64px; cursor: pointer; overflow: hidden;
    background: #f1f4f7; border: 1px solid var(--line); border-radius: 7px;
    transition: border-color .15s;
}
.gallery-thumb img { display: block; width: 100%; height: 100%; object-fit: contain; }
.gallery-thumb:hover { border-color: var(--accent); }
.gallery-thumb.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.product h1 { font-size: 1.9rem; }
.product .price { font-size: 1.9rem; margin: 18px 0 4px; }
.product .buy { display: flex; gap: 10px; margin: 22px 0; }
.product .spec { width: 100%; margin-top: 26px; font-size: .92rem; }
.product .spec th { width: 40%; color: var(--muted); font-weight: 500; text-transform: none; letter-spacing: 0; font-size: .92rem; }

/* ---------- stars and reviews ---------- */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.stars { display: inline-flex; align-items: center; gap: 6px; }
.stars-glyphs { display: inline-flex; gap: 1px; }
.star { width: 17px; height: 17px; display: block; }
.stars.small .star { width: 14px; height: 14px; }
/* Amber rather than the brand green: a rating is not a call to action, and green stars
   read as "approved" instead of "scored". */
/* Modifiers are namespaced. A bare `.empty` here would also match the layout's
   empty-state utility (.empty { padding: 56px 20px }), which blew each blank star up to a
   40x112 box -- invisible in the markup, obvious only in the rendered page. */
.star.star-full, .star.star-half { fill: #d99b25; }
.star.star-blank { fill: #dfe5ea; }
.star.star-half .half-off { fill: #dfe5ea; }
.star.star-half .half-on { fill: #d99b25; }
.stars-count { color: var(--muted); font-size: .82rem; }
.stars.small + .price { margin-top: 6px; }

a.rating-link { text-decoration: none; display: inline-block; margin: 10px 0 0; }
a.rating-link:hover .stars-count { text-decoration: underline; }

.reviews { display: grid; gap: 26px; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); align-items: start; }
.review-list { display: flex; flex-direction: column; gap: 14px; }
.review {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 18px 20px;
}
.review header { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.review h3 { margin: 0; font-size: 1rem; }
.review p { margin: 10px 0 0; white-space: pre-line; overflow-wrap: anywhere; }
.review-meta { color: var(--muted); font-size: .83rem; margin-top: 6px; }
.verified {
    display: inline-block; font-size: .72rem; letter-spacing: .04em; text-transform: uppercase;
    color: var(--ok); background: var(--ok-bg); border: 1px solid #bfe0d4;
    border-radius: 100px; padding: 2px 8px; margin-left: 4px;
}
.review-write h3 { margin: 0 0 12px; font-size: 1.05rem; }
.review-write .panel > .btn { margin-top: 4px; margin-right: 8px; }
.review-write textarea {
    width: 100%; font: inherit; border: 1px solid var(--line); border-radius: 7px;
    padding: 9px 11px; resize: vertical;
}
.review-write textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Radio buttons drawn as stars. Reversed in the DOM (5 down to 1) so the CSS sibling
   combinator can light up the chosen star and every one before it -- there is no previous-
   sibling selector, and this keeps the whole control working with no JavaScript. */
.rating-input { border: 0; padding: 0; margin: 0 0 16px; }
.rating-input legend { font-size: .85rem; font-weight: 600; margin-bottom: 5px; padding: 0; }
/* Reversed so the sibling combinator below can light the chosen star and every one before
   it -- there is no previous-sibling selector, and this keeps the control working with no
   JavaScript at all. */
.rating-stars { display: flex; flex-direction: row-reverse; justify-content: flex-end; }
.rating-input input { position: absolute; opacity: 0; width: 0; height: 0; }
.rating-input label { cursor: pointer; padding: 2px; line-height: 0; }
.rating-input label .star { width: 26px; height: 26px; fill: #dfe5ea; transition: fill .12s; }
/* The input stars are all star-full glyphs; the fill above is what makes them look unset. */
.rating-input label .star.star-full { fill: #dfe5ea; }
.rating-input input:checked ~ label .star.star-full,
.rating-input label:hover .star.star-full,
.rating-input label:hover ~ label .star.star-full { fill: #d99b25; }
/* Keyboard users get a visible ring on the star itself, since the input is off-screen. */
.rating-input input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 4px; }

@media (max-width: 860px) {
    .reviews { grid-template-columns: 1fr; }
}

/* ---------- forms and buttons ---------- */
input, button, select {
    font: inherit; border-radius: 7px; border: 1px solid var(--line); padding: 9px 11px;
}
input:focus, button:focus, a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn {
    background: var(--accent); color: var(--accent-ink); border: 1px solid var(--accent);
    cursor: pointer; font-weight: 600; text-decoration: none; display: inline-block;
    text-align: center;
    /* Declared here rather than relying on the input/button/select rule above, which does
       not match <a>. Without it an <a class="btn"> renders as bare coloured text while a
       <button class="btn"> beside it looks like a button. .btn.link and .btn.big still
       override, being two classes to this one. */
    padding: 9px 11px; border-radius: 7px;
}
.btn:hover { filter: brightness(1.08); }
.btn.secondary { background: transparent; color: var(--ink); border-color: var(--line); font-weight: 500; }
.btn.secondary:hover { border-color: var(--accent); color: var(--accent); filter: none; }
.btn.link { background: none; border: none; color: var(--accent); padding: 0; cursor: pointer; text-decoration: underline; }
.btn.big { padding: 12px 22px; font-size: 1.02rem; }
.btn[disabled] { opacity: .45; cursor: not-allowed; filter: none; }
.qty { width: 84px; }

/* ---------- panels, tables, flashes ---------- */
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; }
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 12px 10px; border-bottom: 1px solid var(--line); }
th { font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tfoot td { border-bottom: none; padding-top: 10px; }
tfoot tr:last-child td { font-size: 1.15rem; font-weight: 700; border-top: 2px solid var(--ink); }

.cart-thumb { width: 56px; height: 56px; object-fit: contain; background: #f1f4f7; border-radius: 6px; flex: none; }
.cart-line { display: flex; gap: 12px; align-items: center; }

.flash { border-radius: 8px; padding: 12px 15px; margin-bottom: 20px; border: 1px solid; }
.flash.ok { background: var(--ok-bg); border-color: #bfe0d4; color: var(--ok); }
.flash.bad { background: var(--danger-bg); border-color: #f3c9c6; color: var(--danger); }

.form-narrow { max-width: 460px; }
.field { margin-bottom: 15px; }
.field label { display: block; font-size: .85rem; font-weight: 600; margin-bottom: 5px; }
.field input { width: 100%; }
.field .err { color: var(--danger); font-size: .82rem; margin-top: 5px; }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.empty { text-align: center; padding: 56px 20px; color: var(--muted); }

/* ---------- account ---------- */
.pill {
    display: inline-block; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 100px; background: var(--accent-wash); color: var(--accent);
    border: 1px solid #c9e0d7;
}
.acct-nav { display: flex; gap: 16px; margin-bottom: 22px; font-size: .95rem; }
.acct-nav a { text-decoration: none; }
.acct-nav a.on { font-weight: 700; }

/* ---------- newsletter + footer ---------- */
.newsletter {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 26px 28px; margin-top: 40px;
    display: flex; align-items: center; justify-content: space-between; gap: 22px; flex-wrap: wrap;
}
.newsletter p { margin: 4px 0 0; color: var(--muted); font-size: .92rem; }

footer.site { border-top: 1px solid var(--line); padding: 30px 0; color: var(--muted); font-size: .87rem; background: var(--panel); }
footer.site .cols { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); margin-bottom: 24px; }
footer.site h4 { margin: 0 0 10px; font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
footer.site ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
footer.site a { text-decoration: none; }
footer.site a:hover { text-decoration: underline; }
footer.site .base { border-top: 1px solid var(--line); padding-top: 18px; }

@media (max-width: 860px) {
    .product { grid-template-columns: 1fr; gap: 24px; }
}
@media (max-width: 860px) {
    /* The search field would otherwise squeeze the brand and the util nav out of a
       single 68px row, so the bar wraps and search takes the full second line. */
    header.site .bar { flex-wrap: wrap; height: auto; padding-top: 12px; padding-bottom: 12px; gap: 12px 20px; }
    .search { order: 3; flex: 1 0 100%; margin-left: 0; }
}
@media (max-width: 620px) {
    .row2 { grid-template-columns: 1fr; }
    header.site nav.util { gap: 12px; }
    /* The brand and the util nav share one line here, so the mark gives back the room. */
    .brand { gap: 8px; font-size: 1.05rem; }
    .brand-mark { height: 30px; }
    .hero { padding: 34px 24px; }
}
@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; }
}
