/*
| Chivoli brand stylesheet (specification section 1: branding & visual identity)
| Colours follow accessible_chivoli_specifications.txt:
|   Primary Leaf Dark Green #1E392A, Secondary Leaf Green #3E6B3B,
|   Light Leaf Green #6FAF5F, Background Pale Green #CFE5C1,
|   Chivoli Gold #D4AF37, Soft Grey #E0E0E0, Dark Slate #2B3A33.
| Typography: Poppins/Nunito (digital), fallback Arial/Helvetica.
*/
:root {
    --leaf-dark: #1E392A;
    --leaf-green: #3E6B3B;
    --leaf-light: #6FAF5F;
    --bg-pale: #CFE5C1;
    --gold: #D4AF37;
    --grey: #E0E0E0;
    --slate: #2B3A33;

    /* Product pictures are always square: both sides use these sizes, so the
       picture stays a square of the height setting (140px tiles / 260px page). */
    --product-img-size: 140px;
    --product-img-size-large: 260px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: 'Nunito', 'Poppins', Arial, Helvetica, sans-serif;
    font-weight: 400;
    line-height: 1.6;
    letter-spacing: 0.2px;
    color: var(--slate);
    background: #fff;
}

h1, h2, h3, h4 { font-weight: 700; color: var(--leaf-dark); line-height: 1.3; }
a { color: var(--leaf-green); }
a:hover { color: var(--leaf-dark); }

/* Header / branding */
.site-header {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 12px 16px;
    background: #fff;
    border-bottom: 1px solid var(--grey);
    flex-wrap: wrap;
}

.brand { display: flex; align-items: center; min-width: 80px; padding: 0 16px; text-decoration: none; }
.brand-logo { width: 160px; height: auto; }
.brand-title { font-weight: 700; font-size: 1.6rem; color: var(--leaf-dark); }
.brand-reg { color: var(--leaf-dark); font-size: .8rem; vertical-align: super; }

.site-nav { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; flex: 1; }
.site-nav a { text-decoration: none; font-weight: 600; padding: 6px 10px; border-radius: 6px; }
.site-nav a:hover { background: var(--bg-pale); }

/* THE MENU IN TWO (the farm, 2026-09-26): the Work / Shopping buttons, and a SuperAdmin's five Work groups.
   Work sits at the left of the shopping menu and Shopping at the right of the work menu, so each button is
   always where the other world left it. */
.site-nav a.world-switch {
    background: var(--leaf-dark);
    color: #fff;
    border: 1px solid var(--leaf-dark);
}
.site-nav a.world-switch:hover { background: var(--leaf-green); border-color: var(--leaf-green); }
.site-nav a.world-switch--right { margin-left: auto; }
.site-nav .world-groups { display: flex; gap: 8px; flex-wrap: wrap; }
.site-nav a.group-button {
    background: var(--bg-pale, #f2f5f2);
    border: 1px solid var(--grey);
}
.site-nav a.group-button.is-active {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--slate);
}
.site-nav a.is-current { background: var(--bg-pale); text-decoration: underline; }

/* THE ACCOUNT CORNER, IN TWO LINES (the farm, 2026-10-08): *"Can the Download Mobile app and name of logged on user be
   above the cart and logout button."* So the invitation and the name stand on the top line (`.user-area-top`), and the
   cart, the box and the way out stand beneath them (`.user-area-main`) — right-aligned, so the corner reads as one
   block against the header's own right edge. A visitor has no top line at all: the cart and the way in stand alone. */
.user-area { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.user-area-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.user-area-main { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
.user-name { font-weight: 600; color: var(--leaf-dark); }
.viewing-badge { background: var(--gold); color: var(--slate); padding: 2px 10px; border-radius: 999px; font-weight: 700; font-size: .85rem; }

/* AN UPDATE IS WAITING (the farm, 2026-10-06) — the top-right notice for a signed-in person whose phone is behind.
   Drawn by resources/views/layouts/app.blade.php only when App\Support\TheApp::isNewerThan() says so, so it is a
   standing invitation rather than decoration: it stands beside the cart and the box, and it goes away the moment the
   phone tells the server it has been updated. */
.app-update {
    background: var(--leaf-green);
    color: #fff;
    padding: 3px 12px;
    border-radius: 999px;
    font-weight: 700;
    font-size: .85rem;
    text-decoration: none;
    white-space: nowrap;
}
.app-update:hover { background: var(--leaf-dark); }

/* The cart in the account corner: the label sits above the picture ("Empty", or how many
   items are waiting). It stands on the LOWER line of the corner, beside the box and the way out — the farm's own order
   (2026-10-08): the app invitation and the person's name are the line above. It is the way into the cart. */
.cart-widget {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    text-decoration: none;
    color: var(--leaf-dark);
    padding: 4px 8px;
    border-radius: 8px;
    border: 1px solid transparent;
    line-height: 1;
}
.cart-widget:hover { background: var(--bg-pale); border-color: var(--grey); }
.cart-widget-label {
    font-family: 'Poppins', sans-serif;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #777;
    white-space: nowrap;
}
.cart-widget-icon { width: 26px; height: 26px; display: block; }
/* A cart with something in it reads as "yours, waiting" rather than "empty". */
.cart-widget-full { color: var(--leaf); }
.cart-widget-full .cart-widget-label { color: var(--leaf-dark); }
.cart-widget-full .cart-widget-icon { width: 30px; height: 30px; }

/* The box beside the cart (the farm, 2026-09-23): what has been PAID FOR and not yet received. It wears the
   gold of "waiting for you" so it is never mistaken for the cart, which is what is not paid for yet. */
.box-widget { color: var(--gold-dark, #8a6d00); }
.box-widget .cart-widget-label { color: var(--gold-dark, #8a6d00); }
.box-widget:hover { border-color: var(--gold-dark, #8a6d00); }

@media (max-width: 720px) {
    .cart-widget-icon { width: 22px; height: 22px; }
    .cart-widget-full .cart-widget-icon { width: 24px; height: 24px; }
}

/* A MARKER THAT EXPLAINS ON HOVER (the farm, 2026-10-08): *"On the website remove all big explanations and make them
   dialogue pop up when the option is hoovered over."*

   The explanation lives in the marker's own `data-why` (written by resources/views/partials/why.blade.php), so there is
   nothing to fetch and nothing to run: `content: attr(data-why)` puts it in a box under the marker on hover — and on
   :focus, so a keyboard reaches it too. The box never takes the mouse, so moving towards it does not snatch it away. */
.why {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    margin-left: 5px;
    border: 1px solid var(--grey);
    border-radius: 50%;
    background: #fff;
    color: var(--leaf-dark);
    font-size: .62rem;
    font-weight: 700;
    font-style: normal;
    line-height: 1;
    cursor: help;
    position: relative;
    vertical-align: middle;
}
.why:hover, .why:focus { background: var(--bg-pale); border-color: var(--leaf-dark); outline: none; }

/* THE LOGO OFFERS HOW TO REACH US (the farm, 2026-10-08): *"If someone clicks or hoovers over (on the web) or touch (on
   app) on the logo, give them a dialogue box that says ..."* The wrapper around the logo wears THE SAME BOX as a marker
   — on hover, and on keyboard focus — and a CLICK opens the real dialogue (a native <dialog>, so it is a dialogue box
   rather than a hint that vanishes). */
.brand-why { position: relative; display: inline-flex; align-items: center; cursor: help; }

/* THE DIALOGUE THE LOGO OPENS (the farm, 2026-10-08): a native <dialog> wearing the site's own face — the words the farm
   gave, the way to the shop, and a way out. */
.contact-dialog {
    border: 1px solid var(--grey);
    border-radius: 10px;
    padding: 18px 20px;
    max-width: 420px;
    background: #fff;
    color: var(--slate);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .18);
}
.contact-dialog::backdrop { background: rgba(0, 0, 0, .35); }
.contact-dialog p { margin: 0 0 14px; font-size: 1rem; line-height: 1.45; }
.contact-dialog-actions { display: flex; gap: 8px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }

.why::after,
.brand-why::after {
    content: attr(data-why);
    position: absolute;
    top: 150%;
    left: 50%;
    transform: translateX(-50%);
    width: 300px;
    max-width: 78vw;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--leaf-dark);
    color: #fff;
    font-size: .78rem;
    font-weight: 400;
    line-height: 1.35;
    text-align: left;
    white-space: normal;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .18);
    opacity: 0;
    visibility: hidden;
    transition: opacity .12s ease;
    z-index: 40;
    pointer-events: none;
}
.why:hover::after, .why:focus::after,
.brand-why:hover::after, .brand-why:focus-within::after { opacity: 1; visibility: visible; }
/* A marker with nothing to say is not drawn at all — which is also how a marker waiting for a script to fill it in stays
   out of the way until it has something to show. */
.why[data-why=""] { display: none; }
/* A marker near the right edge would push its box off the page, so it opens from its own right corner instead. */
.user-area .why::after, .page-heading .why::after { left: auto; right: 0; transform: none; }

/* Layout */
.container { max-width: 1200px; margin: 0 auto; padding: 24px 16px 64px; }
.page-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.card { border: 1px solid var(--grey); border-radius: 10px; padding: 16px; background: #fff; }
.card h3 { margin-top: 0; }
.card.tinted { background: var(--bg-pale); }

.notice { background: var(--bg-pale); border-left: 4px solid var(--leaf-green); padding: 10px 14px; border-radius: 6px; margin-bottom: 16px; }
.notice.warning { border-left-color: var(--gold); background: #FBF6E3; }
.notice.error { border-left-color: #B3402A; background: #FBEDE8; }
/* Buttons */
.btn {
    display: inline-block;
    border: 1px solid var(--leaf-green);
    background: var(--leaf-green);
    color: #fff;
    font-weight: 600;
    font-family: inherit;
    font-size: .95rem;
    padding: 8px 16px;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    min-width: 80px;
}
.btn:hover { background: var(--leaf-dark); border-color: var(--leaf-dark); color: #fff; }
.btn.gold { background: var(--gold); border-color: var(--gold); color: var(--slate); }
.btn.gold:hover { filter: brightness(.92); color: var(--slate); }
.btn.ghost { background: #fff; color: var(--leaf-green); }
.btn.ghost:hover { background: var(--bg-pale); color: var(--leaf-dark); }
.btn.danger { background: #B3402A; border-color: #B3402A; }
.btn.small { padding: 4px 10px; font-size: .85rem; }
.inline-form { display: inline; }

/* Forms */
form .field { margin-bottom: 14px; }
label { display: block; font-weight: 600; margin-bottom: 4px; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=datetime-local], select, textarea {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--grey);
    border-radius: 8px;
    font: inherit;
    background: #fff;
    color: var(--slate);
}
textarea { min-height: 90px; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--leaf-light); border-color: var(--leaf-light); }
.error-text { color: #B3402A; font-size: .85rem; margin-top: 2px; }

/* Tables */
.table-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; background: #fff; }
table.data th, table.data td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--grey); vertical-align: top; }
table.data th { background: var(--bg-pale); color: var(--leaf-dark); font-weight: 700; }
table.data tr:hover td { background: #F6FAF3; }

/* Badges */
.badge { display: inline-block; padding: 1px 10px; border-radius: 999px; font-size: .8rem; font-weight: 700; background: var(--grey); color: var(--slate); }
.badge.green { background: var(--leaf-light); color: #fff; }
.badge.dark { background: var(--leaf-dark); color: #fff; }
.badge.gold { background: var(--gold); color: var(--slate); }
.badge.red { background: #B3402A; color: #fff; }

/* Product tiles (storefront) */
.product-tile { display: flex; flex-direction: column; gap: 6px; }
.product-tile .price { font-size: 1.15rem; font-weight: 700; color: var(--leaf-dark); }
.product-tile .was { text-decoration: line-through; color: #8a8a8a; font-size: .9rem; }
.img-placeholder {
    width: var(--product-img-size); height: var(--product-img-size);
    border-radius: 8px; background: var(--bg-pale);
    display: flex; align-items: center; justify-content: center; color: var(--leaf-green);
    font-weight: 700;
}
.img-placeholder--large {
    width: var(--product-img-size-large); height: var(--product-img-size-large);
}

/* Product images (uploaded pictures) — square, sized from the height setting */
.product-img {
    width: var(--product-img-size);
    height: var(--product-img-size);
    object-fit: cover;
    border-radius: 8px;
    background: var(--bg-pale);
}
.product-img--large {
    width: var(--product-img-size-large);
    height: var(--product-img-size-large);
}
.product-thumb {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: 8px;
    background: var(--bg-pale);
    display: block;
}

/* Bundle covers (spec 10.15) — two of the bundle's items, half the tile each */
.bundle-cover { display: flex; gap: 6px; width: 100%; }
.bundle-cover .bundle-cover-item { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bundle-cover .bundle-cover-img,
.bundle-cover .bundle-cover-placeholder {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: 8px;
    background: var(--bg-pale);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--leaf-green);
    font-weight: 700;
}
.bundle-cover .bundle-cover-name {
    font-size: .8rem;
    color: #6c6c6c;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bundle-cover--small { max-width: 220px; }

/* Product ribbons (spec 10.7) — very brief taglines under the product */
.product-ribbons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ribbon {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--gold);
    color: var(--slate);
    font-size: .8rem;
    font-weight: 700;
}

/* THE PRODUCT'S OWN STARS, JUST TO THE LEFT OF ITS RIBBON (the farm, 2026-09-30): "For each product in the store,
   just to the left of the ribbon, please show the average number of stars." The stars and the ribbon share one line,
   the stars first — and a product nobody has rated yet has no stars there at all rather than five empty ones. */
.shelf-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }
.shelf-line .product-ribbons { margin-top: 0; }
.shelf-line .rating { margin: 0; }

/* ONE PERSON'S LINE ON THE STARS PAGE (the farm, 2026-09-30): who did what for a purchase, and the button that lays
   the customer's own score at their feet. */
.hand {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 10px;
    flex-wrap: wrap;
    padding: 6px 0;
    border-top: 1px solid var(--soft-grey);
}
.hand:first-of-type { border-top: 0; }
.staff-stars { padding: 8px 0; border-top: 1px solid var(--soft-grey); }
.staff-stars:first-of-type { border-top: 0; }

/* Only for screen readers */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Farm flash lines (spec 10.7) — a strip across the very top of the page.
   Each line sweeps in from the right one character at a time and leaves on the
   left, so no line ever sits still in the middle of the screen. */
.site-flash {
    position: relative;
    overflow: hidden;
    height: 34px;
    /* Space kept between two flash lines — about an inch. */
    --flash-gap: 96px;
    background: var(--leaf-dark);
    color: #fff;
    font-weight: 700;
    letter-spacing: .4px;
    border-bottom: 1px solid var(--gold);
}
/* SOMETHING THEY FOLLOW IS FREE NOW (the farm, 2026-09-26): the ticker's message becomes the farm's sentence —
   still, readable at a glance, and wearing the gold, because it is a "now or never" and the shopper is already
   looking at the page. */
.site-flash--followed {
    animation: chivoli-closing-flash 1.6s ease-in-out infinite;
}
.site-flash--followed .site-flash__line--still {
    position: static;
    height: auto;
    min-height: 34px;
    justify-content: center;
    text-align: center;
    padding: 4px 14px;
    font-size: .95rem;
}
@media (prefers-reduced-motion: reduce) {
    .site-flash--followed { animation: none; }
}

/* THE CLOSING WARNING (the farm, 2026-09-24): the flashing strip that replaces the scrolling flash lines in the
   last twenty minutes before the shop shuts. It flashes rather than scrolls — the message must be readable at a
   glance — and it wears the gold, like everything else that is waiting. */
.site-closing {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 34px;
    padding: 4px 14px;
    background: var(--gold-dark, #8a6d00);
    color: #fff;
    font-weight: 700;
    letter-spacing: .3px;
    border-bottom: 1px solid var(--leaf-dark);
    animation: chivoli-closing-flash 1.6s ease-in-out infinite;
}
.site-closing__text { max-width: 1400px; }
@keyframes chivoli-closing-flash {
    0%, 100% { background: var(--gold-dark, #8a6d00); color: #fff; }
    50% { background: #fff; color: var(--gold-dark, #8a6d00); }
}
/* Anyone who asked for less movement gets the same message without the flashing: readable, never silent. */
@media (prefers-reduced-motion: reduce) {
    .site-closing { animation: none; }
}


.site-flash__line {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    display: flex;
    align-items: center;
    white-space: nowrap;
    will-change: transform;
}
.site-flash--static {
    height: auto;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    padding: 8px 14px;
}
.site-flash--static .site-flash__line { position: static; }

/* Sabbath rest (spec 10.9) — the site is readable but nothing responds, and
   the Sabbath message is the only thing that flashes. */
html.sabbath-on, html.sabbath-on body { overflow: hidden; }
.sabbath-veil {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: var(--leaf-dark);
    color: #fff;
    display: flex;
    align-items: flex-start;
    justify-content: center;
}
.sabbath-flash {
    width: 100%;
    height: 64px;
    margin-top: 18vh;   /* upper part of the screen, never the middle */
    background: transparent;
    border: 0;
    font-size: 1.35rem;
    letter-spacing: .6px;
}

/* Footer */
.site-footer { border-top: 1px solid var(--grey); padding: 16px; text-align: center; color: var(--leaf-green); background: #fff; }
.site-footer .footer-logo { width: 140px; opacity: .85; vertical-align: middle; }
/* The credit the farm asked for (2026-09-24): quieter than the farm's own line above it, with the address
   (www.rapidity.today) as a link. */
.site-footer .footer-credit { margin-top: 6px; font-size: .8rem; color: var(--earth, #6b5b47); letter-spacing: .3px; }
.site-footer .footer-credit a { color: var(--leaf-dark); text-decoration: underline; }

/* WHAT CUSTOMERS SAY (the farm, 2026-09-30): the three ratings shown apart, and the five stars a shopper taps.
   "Specific ratings. Separate ratings." — the styling follows that rule too: every score wears its own row and
   its own label, and nothing is ever printed as one blended number. */
.rating { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rating-stars { color: var(--gold); letter-spacing: 1px; font-size: 1rem; }
.rating-label { color: var(--slate); font-size: .85rem; }
.rating-block { border-top: 1px solid var(--grey); padding: 10px 0; }
.rating-block:first-of-type { border-top: 0; }
.rating-block .rating-what { font-weight: 700; color: var(--leaf-dark); }
.rating-breakdown { font-size: .8rem; color: #6c6c6c; margin: 4px 0 0; }

/* The five stars in the form: radios underneath, stars on top, 1 on the left. row-reverse is what makes
   "everything up to the star you touched" light up without a line of JavaScript. */
.star-picker { display: inline-flex; flex-direction: row-reverse; gap: 2px; justify-content: flex-end; }
.star-picker input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.star-picker label { cursor: pointer; font-size: 1.7rem; line-height: 1; color: #cfcfcf; padding: 0 2px; }
.star-picker input:checked ~ label,
.star-picker label:hover,
.star-picker label:hover ~ label { color: var(--gold); }
.star-picker input:focus-visible + label { outline: 2px solid var(--leaf-green); outline-offset: 2px; }

/* The wall of voices */
.voice { border-bottom: 1px solid var(--grey); padding: 10px 0; }
.voice:last-child { border-bottom: 0; }
.voice-what { font-weight: 700; color: var(--leaf-dark); }
.voice-when { font-size: .8rem; color: #6c6c6c; }
.voice-body { margin: 4px 0 0; }

/* Print (spec 1.3) */
@media print {
    .site-header, .site-nav, .btn, .site-footer, .site-flash, .sabbath-veil { display: none; }
    body { color: #000; font-size: 10pt; }
}

