/*
 * components.css
 * Reusable, cross-module component styles (CSS-02).
 *
 * Every rule below was moved here only after confirming byte-identical
 * (or functionally identical, inert-difference-only) source content and
 * real consumers, so this migration introduces no visual change.
 *
 * Section 1 is consumed by the Seller/Supervisor/Fieldbook layouts.
 * Section 2 is consumed by the Frontend/Backend/Auth layouts (the
 * "store" loader also used by wholesaler.css/customer.css consumers).
 * Do not add design-token/color changes here (reserved for a future
 * token-consolidation pass) or module-exclusive rules (see modules/*.css).
 */

/* =======================================================================
 * SECTION 1 - Seller / Supervisor / Fieldbook shared layout styles
 * ======================================================================= */

/* Origin: public/assets/css/seller.css (misleadingly named — it was
 * already loaded identically by all three module layouts).
 * Consumers: seller/inc/seller_nav.blade.php, supervisor/inc/supervisor_nav.blade.php */
.wholesale_color {
    color: #3322BF !important;
}

.customer_color {
    color: #BA0572 !important;
}

#dark-mode-toggle .la-moon {
    display: none;
}

.dark-mode #dark-mode-toggle .la-sun {
    display: none;
}

.dark-mode #dark-mode-toggle .la-moon {
    display: inline;
}

/* Origin: embedded <style> block duplicated verbatim across
 * seller/layouts/app.blade.php, supervisor/layouts/app.blade.php and
 * fieldbook/layouts/app.blade.php. */
body {
    font-size: 12px;
}

#map {
    width: 100%;
    height: 250px;
}

#edit_map {
    width: 100%;
    height: 250px;
}

.pac-container {
    z-index: 100000;
}

.oculto {
    display: none;
}

/* Historical note: the Fieldbook layout copy-pasted this block from
 * Seller and kept the "loader_seller" class name even though it is the
 * Fieldbook layout's own loader; several Fieldbook views still reference
 * #loader_seller directly, so the class name is preserved as-is here
 * rather than renamed (out of scope for this pass). */
.loader_seller,
.loader_supervisor {
    border: 5px solid #f3f3f3;
    border-top: 5px solid #3498db;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    animation: aiz-module-spin 2s linear infinite;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 9999;
    display: none;
}

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 9998;
    display: none;
}

@keyframes aiz-module-spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

/* =======================================================================
 * SECTION 1B - Module cards (PRODUCT-FORM-01)
 * =======================================================================
 *
 * Every Bootstrap/AIZ `.card` rendered by the Seller, Supervisor or
 * Fieldbook layout (body.theme-*) gets the module look: a border tinted
 * with the module primary, a soft shadow that lifts it off the page and a
 * header tinted and titled with that primary. Rules and exceptions in
 * UI_VISUAL_STANDARD.md §14.
 *
 * Colours come only from the module theme tokens (--app-*, modules/*.css),
 * never from a role name, so the same rules give Seller burgundy,
 * Supervisor blue and Fieldbook green. The --card-* tokens are the knobs:
 * a view or component that needs another look sets them on its own
 * element instead of re-declaring the properties.
 *
 * :where() keeps every selector at AIZ's own weight (.card .card-header,
 * 0,2,0 at most), so whatever already styles a card on purpose still wins:
 * utility backgrounds, borders and shadows (bg-*, border-*, shadow-*, all
 * !important), coloured cards (card text-white bg-*), .kit-card,
 * .additional-accordion, .card.status-* and a view's own <style>.
 * Summernote's editor (.note-editor.card) and the uploader's file tiles
 * (.card-file) are widgets built on .card, not cards, and are left out. */
:where(.theme-seller, .theme-supervisor, .theme-fieldbook) {
    --card-accent: var(--app-primary);
    --card-accent-soft: color-mix(in srgb, var(--app-primary-soft) 70%, var(--app-surface));
    --card-border: var(--app-border);
    /* --app-muted darkened toward --app-ink: Bootstrap's .text-muted grey
     * falls under 4.5:1 on the tinted header, this stays above 5.5:1. */
    --card-muted: color-mix(in srgb, var(--app-muted) 80%, var(--app-ink));
    --card-radius: 14px;
    --card-shadow: 0 4px 16px color-mix(in srgb, var(--app-ink) 6%, transparent);
}

:where(.theme-seller, .theme-supervisor, .theme-fieldbook) .card:where(:not(.note-editor, .card-file)) {
    border-color: var(--card-border);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
}

:where(.theme-seller, .theme-supervisor, .theme-fieldbook) .card:where(:not(.note-editor, .card-file, .text-white)) > .card-header {
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
    border-bottom-color: var(--card-border);
    background-color: var(--card-accent-soft);
    color: var(--card-accent);
}

/* !important only because Bootstrap's .text-muted is !important. */
:where(.theme-seller, .theme-supervisor, .theme-fieldbook) .card:where(:not(.note-editor, .card-file, .text-white)) > .card-header .text-muted {
    color: var(--card-muted) !important;
}

/* =======================================================================
 * SECTION 2 - Store page loader (Frontend / Backend / Auth)
 * ======================================================================= */

/* Origin: duplicated across public/assets/css/wholesaler.css,
 * public/assets/css/customer.css and the inline <style> in
 * backend/layouts/app.blade.php. customer.css and the backend layout
 * carried an inert/invalid "color: #BA0572(255, 61, 0, 0.9)" declaration
 * on .loader (the browser drops it as invalid); the spinner's visuals
 * come entirely from box-shadow via the fill/fillNeck keyframes, so
 * that property has zero visual effect and is normalized here to the
 * one valid value wholesaler.css used.
 * Markup consumers: resources/views/frontend/partials/loader.blade.php
 * and backend/layouts/app.blade.php's own inline markup. */
.loader {
    width: 40px;
    height: 98px;
    display: inline-block;
    position: relative;
    border: 2px solid #FFF;
    box-sizing: border-box;
    color: #BA0572;
    border-radius: 20px 20px 4px 4px;
    background: #fff;
    animation: fill 2s linear infinite alternate;
}

.loader::after {
    content: '';
    box-sizing: border-box;
    position: absolute;
    left: 50%;
    top: 0%;
    transform: translate(-50%, -95%);
    border: 2px solid #FFF;
    border-bottom: none;
    background: #fff;
    width: 15px;
    height: 35px;
    animation: fillNeck 2s linear infinite alternate;
}

@keyframes fill {
    0% {
        box-shadow: 0 0 inset
    }

    50%,
    100% {
        box-shadow: 0 -98px inset
    }
}

@keyframes fillNeck {

    0%,
    50% {
        box-shadow: 0 0 inset
    }

    100% {
        box-shadow: 0 -20px inset
    }
}

.loader-section {
    width: 100vw;
    height: 100vh;
    max-width: 100%;
    position: fixed;
    top: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #ffffff;
    z-index: 999;
    transition: all 1s 1s ease-out;
    opacity: 1;
}

.loaded {
    opacity: 0;
    z-index: -1;
}

/* =======================================================================
 * SECTION 3 - Buttons & action groups (CSS-04A)
 * =======================================================================
 *
 * This section does NOT replace AIZ/Bootstrap's button vocabulary
 * (`btn`, `btn-primary`, `btn-soft-*`, `btn-icon`, `btn-circle`, `btn-sm`,
 * defined in aiz-core.css / aiz-seller.css). That vocabulary already
 * covers color/size/shape and is reused as-is. What was missing was a
 * single, centralized definition of the "action group" pattern (a row of
 * action buttons in a card/table footer, with an optional "More" dropdown
 * for overflow) — until now each view duplicated its own version of these
 * same rules locally (see `.product-list-actions` in
 * seller/components/product_table.blade.php prior to CSS-04A, the best
 * existing precedent, per documentation/ui_style_audit/07-component-strategy.md#7).
 *
 * Usage: add `action-group` to the element that wraps a row of action
 * buttons (in addition to, or instead of, any existing view-local class).
 * Primary actions are visible buttons directly inside it; secondary/
 * overflow actions go inside a `.dropdown` "More" button using Bootstrap's
 * existing dropdown markup (`dropdown-toggle` + `dropdown-menu` +
 * `dropdown-item`) — no new dropdown component needed.
 */
.action-group {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .35rem;
}

.action-group form {
    margin: 0;
}

/* Scoped to :not(.btn-icon): aiz-core.css gives .btn-sm.btn-icon an
 * explicit square width+height (~34px) for its circular shape. An
 * unscoped min-height here would win over that height (38 > 34) while
 * leaving width untouched, turning every icon-circle button into an
 * oval. Text buttons (no btn-icon) have no such fixed height, so this
 * still raises their tap target as originally intended. */
.action-group .btn:not(.btn-icon) {
    min-height: 38px;
}

.action-group .dropdown-menu {
    min-width: 210px;
}

.action-group .dropdown-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-height: 38px;
}

.action-group .dropdown-item i {
    width: 18px;
    text-align: center;
}

@media (max-width: 767px) {
    .action-group {
        justify-content: flex-start;
        width: 100%;
    }
}

/* Minimal accessibility (CSS-04A, §10): icon-only buttons (`btn-icon`)
 * carry no visible text, so keyboard focus must not rely on color alone.
 * aiz-core.css's `.btn:focus:not(.btn-shadow) { box-shadow: none }` only
 * removes a box-shadow — it does not set `outline`, so this addition is
 * purely additive and does not change mouse-click appearance. Scoped to
 * `:focus-visible` (keyboard/programmatic focus) rather than plain
 * `:focus`, and to `.btn-icon` rather than every button, to keep this a
 * targeted accessibility fix instead of a global visual change. */
.btn-icon:focus-visible {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 2px;
}

/* CSS-10B1: themed primary buttons (Seller/Supervisor/Fieldbook).
 *
 * aiz-core.css/aiz-seller.css's .btn-primary/.btn-soft-primary/
 * .btn-outline-primary already resolve through var(--primary)/
 * var(--hov-primary)/var(--soft-primary), which CSS-10A's modules/*.css
 * already remaps per theme on <body class="theme-*">. Color is therefore
 * already correct with zero changes here — this section only adds the
 * geometry/finish Proposal D established as the approved button language
 * (compact, moderate radius, clean border, visible focus), once, shared
 * by all three themes instead of duplicated in each modules/*.css file.
 *
 * Radius/weight are scoped to .theme-seller/.theme-supervisor/
 * .theme-fieldbook (not global) so Backend/Frontend — which load this
 * same components.css but never carry a theme-* class — keep their exact
 * previous geometry (CSS-10B1 §14). No change to height/padding/action-
 * group spacing.
 */
.theme-seller .btn-primary,
.theme-seller .btn-soft-primary,
.theme-seller .btn-outline-primary,
.theme-supervisor .btn-primary,
.theme-supervisor .btn-soft-primary,
.theme-supervisor .btn-outline-primary,
.theme-fieldbook .btn-primary,
.theme-fieldbook .btn-soft-primary,
.theme-fieldbook .btn-outline-primary {
    border-radius: 6px;
    font-weight: 600;
}

/* Soft button border: `--app-border` is only defined under a theme-* body
 * (CSS-10A), so the fallback keeps Backend/Frontend byte-identical to
 * before — Bootstrap's base .btn already ships a 1px solid transparent
 * border, this only changes its color where a theme is active. */
.btn-soft-primary {
    border-color: var(--app-border, transparent);
}

/* Same additive, keyboard-only pattern as .btn-icon:focus-visible above —
 * safe everywhere, themed where --app-focus exists. */
.btn-primary:focus-visible,
.btn-soft-primary:focus-visible,
.btn-outline-primary:focus-visible {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 2px;
}

/*
 * UI-PASS-05: `.btn-doc` — the toolbar-level button for download / export /
 * "get the document" actions.
 *
 * These actions were reaching for Bootstrap's `.btn-info` (a fixed cyan that
 * belongs to the semantic-state layer, not to an action) in six listings across
 * the three modules. The application already has ONE colour for this meaning:
 * `--entity-action-doc`, used by the `.entity-action--doc` card/row action. This
 * variant reuses that same token so the toolbar button and the row action of the
 * same page say the same thing, in one shared implementation.
 *
 * It is the toolbar form factor only: `.entity-action` is the icon-over-label
 * tile of a card footer and is not interchangeable with a `.btn`.
 *
 * Consumers: the "Download all …" buttons of the three viticulturist listings,
 * Fieldbook Plots, Seller Harvest, and the Fieldbook calendar CSV export.
 */
.btn-doc {
    color: var(--entity-action-doc);
    background: var(--entity-action-doc-soft);
    border: 1px solid var(--entity-action-doc);
    font-weight: 600;
}

.btn-doc:hover,
.btn-doc:focus {
    color: #fff;
    background: var(--entity-action-doc);
    border-color: var(--entity-action-doc);
}

.btn-doc:focus-visible {
    outline: 2px solid var(--app-focus, var(--entity-action-doc));
    outline-offset: 2px;
}

/* CSS-10B2: themed alerts, badges & status states (Seller/Supervisor/
 * Fieldbook).
 *
 * Three color layers stay separate here (per spec):
 *  - Module identity (primary/accent) -> themed below, alert-primary only.
 *  - Semantic state (success/warning/danger/info, pending/approved/
 *    rejected/completed/cancelled) -> untouched, fixed regardless of
 *    module.
 *  - Domain color (Mosto/Tinto/Blanco/Rosado, .badge-must, .pill-must)
 *    -> untouched, out of scope.
 *
 * Badges: .badge-primary/.badge-soft-primary (aiz-core.css/aiz-seller.css)
 * already resolve through var(--primary)/var(--soft-primary), already
 * remapped per theme by CSS-10A — zero color change needed, same finding
 * as CSS-10B1's buttons. Their base .badge box model is AIZ's small
 * 18x18 counter/notification badge, unrelated to the status-pill system
 * below, so nothing to modernize there either.
 *
 * Alerts: unlike badges, `.alert`/`.alert-primary` are vanilla Bootstrap
 * (vendors.css) with hardcoded hex, never remapped by AIZ or this app, so
 * they need real rules. Scoped to the three theme-* bodies — same
 * regression-safety pattern as CSS-10B1's button radius — so Backend/
 * Frontend (no theme-* class) keep Bootstrap's exact previous alert
 * appearance. alert-success/-warning/-danger/-info keep Bootstrap's
 * semantic colors untouched; only alert-primary adopts theme identity,
 * through the --app-primary/--app-primary-soft/--app-border tokens
 * CSS-10A already defines per theme (with Bootstrap's own defaults as
 * fallback).
 */
.theme-seller .alert,
.theme-supervisor .alert,
.theme-fieldbook .alert {
    padding: 12px 16px;
    border-radius: 6px;
}

.theme-seller .alert-primary,
.theme-supervisor .alert-primary,
.theme-fieldbook .alert-primary {
    color: var(--app-primary, #004085);
    background-color: var(--app-primary-soft, #cce5ff);
    border-color: var(--app-border, #b8daff);
}

/* Status pills (.status-badge, .requestbadge — custom-style.css): the
 * existing system already works and already carries the semantic
 * --status-*-bg tokens from core.css (untouched here). Only a legibility
 * refinement (font-weight, matching the 600 weight already applied to
 * buttons in CSS-10B1), left unscoped since it's purely additive and
 * confirmed unused in backend/frontend views. Radius/padding/width/
 * font-size are deliberately left alone: the real usage sample
 * (supervisor_requests/index.blade.php) shows those exact properties are
 * routinely set inline per-instance, so a shared change there would be
 * silently masked in most consumers and only create inconsistency in the
 * few that don't override it. */
.status-badge,
.requestbadge {
    font-weight: 600;
    border-radius: 3px 8px 3px 8px;
}

/* =======================================================================
 * SECTION 4 - Forms base (CSS-05A)
 * =======================================================================
 *
 * This section does NOT replace Bootstrap's native form-validation
 * classes (`is-invalid`, `invalid-feedback`, defined in vendors.css) or
 * AIZ's own widgets (`aiz-selectpicker` / bootstrap-select, `aiz-switch`,
 * `aiz-uploader`). Those are already the de facto standard across
 * Seller/Supervisor/Fieldbook/Backend (911 `@error` occurrences / 90
 * files already use `is-invalid`/`invalid-feedback`) and are kept as-is.
 * What was missing was:
 *
 * 1) `is-invalid` has zero visible effect on an `aiz-selectpicker`
 *    select: bootstrap-select (v1.13.12) hides the real `<select>` and
 *    copies its classes onto the generated `.bootstrap-select` wrapper
 *    div (not onto the visible `.dropdown-toggle` button), so
 *    `.is-invalid`'s red border never reaches anything on screen. The
 *    rule below cascades that state down onto the visible toggle.
 * 2) Bootstrap's native validation red (#dc3545, vendors.css) is a
 *    slightly different shade than this app's own danger token
 *    (`--danger: #ef486a`, aiz-core.css). Both are already "red" so this
 *    is a low-risk harmonization, not a redesign: it makes every
 *    existing `is-invalid`/`invalid-feedback` usage (inputs, textareas,
 *    selectpickers) resolve to the same brand danger color, without
 *    touching any Blade markup.
 * 3) bootstrap-select's own CSS (`aiz-core.css`) sets
 *    `.dropdown-toggle:focus { outline: none !important }`, the same
 *    kind of focus-outline suppression fixed for icon buttons in
 *    CSS-04A (`.btn-icon:focus-visible` above) — but that pass's fix is
 *    scoped to buttons, so selectpicker keyboard focus stays invisible
 *    without this. This does not touch the separate, still-pending
 *    global `.btn:focus` issue noted in CSS-04A.
 *
 * Label / required-indicator / help-text / validation-message markup
 * conventions are documented in documentation/ui_style_audit/Roadmap_css.md
 * (CSS-05A) rather than enforced via new classes here: the existing
 * Bootstrap utility classes (`col-form-label`, `text-danger`, `text-muted`,
 * `invalid-feedback`) already cover them adequately once used
 * consistently, so no new "form/label", "form/help" etc. wrapper classes
 * were introduced (per CSS-05A's own instruction not to build ceremonial
 * components for patterns Bootstrap already solves).
 */
.is-invalid,
.form-control.is-invalid,
.custom-select.is-invalid {
    border-color: var(--danger);
}

.invalid-feedback {
    color: var(--danger);
}

.bootstrap-select.is-invalid .dropdown-toggle,
.bootstrap-select .dropdown-toggle.is-invalid {
    border-color: var(--danger) !important;
}

.bootstrap-select .dropdown-toggle:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 1px;
}

/* CSS-10B3: themed form controls (Seller/Supervisor/Fieldbook).
 *
 * Color: nothing new, same finding as CSS-10B1/CSS-10B2. `.form-control:focus`
 * (aiz-seller.css/aiz-core.css) already resolves its border through
 * var(--primary), the `.aiz-square-check`/`.aiz-rounded-check` tick marks and
 * `.aiz-megabox`'s checked border likewise — and CSS-10A already remaps
 * --primary per theme. The gaps were geometry and keyboard focus.
 *
 * Radius is scoped to the three theme-* bodies (6px, the same value CSS-10B1
 * gave the primary button family) so Backend/Frontend, which load this file
 * but never carry a theme-* class, keep their exact previous input geometry.
 *
 * Focus: AIZ sets `.form-control:focus { box-shadow: none }`, leaving a 1px
 * border tint as the only focus signal. The :focus-visible outlines below are
 * additive and keyboard-only, the pattern CSS-04A established for .btn-icon
 * and CSS-10B1 for the primary buttons; with var(--app-focus, var(--primary))
 * they resolve to today's value outside the themed apps.
 *
 * `.aiz-checkbox`/`.aiz-radio` hide the real input (opacity:0; z-index:-1) and
 * draw the box in a sibling span, so a focus ring on the input itself is
 * invisible — it has to be carried to that sibling. Native (non-AIZ)
 * checkboxes and radios, which the listings use directly for bulk selection,
 * get accent-color from the module primary; two bespoke classes
 * (.entity-bulk-toolbar__checkbox, .plot_checkbox) already did this
 * individually and resolve to the same token, so nothing conflicts.
 */
.theme-seller .form-control,
.theme-seller .custom-select,
.theme-supervisor .form-control,
.theme-supervisor .custom-select,
.theme-fieldbook .form-control,
.theme-fieldbook .custom-select {
    border-radius: 6px;
}

.form-control:focus-visible,
.custom-select:focus-visible {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 1px;
}

.aiz-checkbox > input:focus-visible ~ .aiz-square-check,
.aiz-checkbox > input:focus-visible ~ .aiz-rounded-check,
.aiz-radio > input:focus-visible ~ .aiz-square-check,
.aiz-radio > input:focus-visible ~ .aiz-rounded-check,
.aiz-megabox > input:focus-visible ~ .aiz-megabox-elem {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 2px;
}

.theme-seller input[type="checkbox"],
.theme-seller input[type="radio"],
.theme-supervisor input[type="checkbox"],
.theme-supervisor input[type="radio"],
.theme-fieldbook input[type="checkbox"],
.theme-fieldbook input[type="radio"] {
    accent-color: var(--app-primary, var(--primary));
}

/* PRODUCT-FORM-01: form building blocks first used by the Seller product
 * create/edit form (rules in UI_VISUAL_STANDARD.md §12, §13 and §15). They
 * are opt-in classes; the module look of the cards themselves is global
 * (SECTION 1B).
 *
 * `.select-media`: rich option content for an `aiz-selectpicker` through the
 * plugin's own `data-content` (image or fallback icon + name). The icon takes
 * the image's box, so names stay aligned when an option has no image; live
 * search still matches the name because bootstrap-select strips the markup
 * before filtering.
 *
 * `.card-header__media`: a decorative picture, or its fallback icon
 * (`--icon`), at the end of a card header (the flex header puts it on the
 * right). The negative margins keep it inside the header's own height, so
 * showing or hiding it never moves the card body.
 *
 * `.attribute-tile`: a yes/no attribute (vegan, ecological, contains
 * sulfites) as one labelled tile: icon + name + state mark, and the whole
 * tile is the click target. The real checkbox stays inside, visually hidden
 * but focusable, so keyboard, screen readers and form posting behave as
 * with any checkbox; its focus ring is drawn on the tile. On and off differ
 * in border, background AND a tick in the state mark, never in colour
 * alone. The tick uses the `/ ""` alternative text so it adds nothing to
 * the accessible name: the checkbox already announces its state. */
.select-media {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
}

.select-media__img {
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.25rem;
    object-fit: contain;
}

.select-media__img--icon {
    font-size: 1.25rem;
    line-height: 1.25rem;
    text-align: center;
    color: var(--app-muted, var(--secondary));
}

.card-header__media {
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2rem;
    margin: -.25rem 0 -.25rem .75rem;
    object-fit: contain;
}

.card-header__media--icon {
    font-size: 1.75rem;
    line-height: 2rem;
    text-align: center;
    color: var(--card-muted, var(--app-muted, var(--secondary)));
}

.attribute-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.attribute-tile {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 2.5rem;
    margin: 0;
    padding: .375rem .75rem;
    border: 1px solid var(--app-border, var(--border-color-neutral));
    border-radius: var(--radius-md, 8px);
    background: var(--app-surface, var(--white));
    color: var(--app-ink, var(--dark));
    font-weight: 500;
    cursor: pointer;
    user-select: none;
    transition: border-color .15s ease, background-color .15s ease;
}

.attribute-tile:hover {
    border-color: var(--app-primary, var(--primary));
}

.attribute-tile__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.attribute-tile__icon {
    font-size: 1.25rem;
    color: var(--app-muted, var(--secondary));
}

.attribute-tile__state {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.125rem;
    height: 1.125rem;
    border: 1.5px solid var(--app-muted, var(--secondary));
    border-radius: 50%;
    font-size: .75rem;
    line-height: 1;
}

.attribute-tile:has(.attribute-tile__input:checked) {
    border-color: var(--app-primary, var(--primary));
    background: var(--app-primary-soft, var(--light));
}

.attribute-tile__input:checked ~ .attribute-tile__icon {
    color: var(--app-primary, var(--primary));
}

.attribute-tile__input:checked ~ .attribute-tile__state {
    border-color: var(--app-primary, var(--primary));
    background: var(--app-primary, var(--primary));
    color: var(--app-surface, var(--white));
}

.attribute-tile__input:checked ~ .attribute-tile__state::before {
    content: "\2713";
    content: "\2713" / "";
}

.attribute-tile:has(.attribute-tile__input:focus-visible) {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 2px;
}

.attribute-tile:has(.attribute-tile__input:disabled) {
    cursor: not-allowed;
    opacity: .6;
}

/* =======================================================================
 * SECTION 5 - Tables & dense listings (CSS-06A)
 * =======================================================================
 *
 * This section does NOT redefine `.aiz-table`, `.table`, `.table-responsive`,
 * `.table-striped`, `.table-hover` or any other Bootstrap/AIZ table rule
 * (those stay exactly as defined in vendors.css / aiz-core.css / aiz-seller.css
 * and remain the base layer). Directed inventory across Seller (115 files),
 * Backend (85), Supervisor (31) and Fieldbook found real, working table
 * markup everywhere; the gap was never the table itself but two repeated
 * omissions: (1) most listings render nothing at all when the dataset is
 * empty (no message, no icon — just a header row with an empty `<tbody>`,
 * or in some cases the whole card body is skipped), and (2) row actions are
 * plain sibling `<a>`/`<button>` tags rather than the `.action-group`
 * pattern already established in Section 3 (CSS-04A). Two Blade components
 * that pre-dated this pass (`components/table/responsive.blade.php`,
 * `components/view/details.blade.php`) were found to have zero real
 * consumers anywhere in resources/views and were deleted rather than kept
 * "just in case" (see Roadmap_css.md, CSS-06A).
 *
 * Row actions: no new class was added for this — reuse `.action-group`
 * (Section 3) inside the actions `<td>` exactly as it is already used in
 * card/list contexts. It already works unmodified inside a table cell.
 *
 * Empty states: `.table-empty` below is the only new rule, pairing with
 * the new `<x-table.empty-row>` component (resources/views/components/table/empty-row.blade.php).
 * It formalizes a pattern that already existed ad hoc in several Fieldbook
 * listings (`text-center text-muted py-5` on a single full-width `<td>`)
 * by adding a small icon for legibility, without inventing a new visual
 * language.
 */
.table-empty {
    padding: 3rem 1rem;
    text-align: center;
    color: #8a8a8a;
}

.table-empty i {
    display: block;
    font-size: 2rem;
    margin-bottom: .5rem;
    color: #c7c7c7;
}

.table-empty p {
    margin: 0;
}

/* CSS-10B3: themed tables & modals (Seller/Supervisor/Fieldbook).
 *
 * Tables. `.aiz-table` carries no identity color at all — its rules
 * (aiz-seller.css/aiz-core.css) are fixed neutrals (#eceff7 rules, no header
 * fill, no hover). Only the header band is themed here, and only with the
 * neutral half of each palette (--app-surface-alt / --app-ink / --app-border),
 * so a listing reads as belonging to its module without recoloring any cell
 * content. Row striping/hover is deliberately NOT introduced: `.table-hover`
 * and `.table-striped` are opt-in per listing today and adding a global hover
 * would change behaviour on every table in the three apps for no stated need.
 *
 * Modals. `.modal-content`/`.modal-content .modal-header` (aiz-seller.css/
 * aiz-core.css) are likewise fixed neutrals (rgba(20,20,35,.2) border,
 * #ebedf2 header rule) and the `.close` button has no focus ring. Border and
 * radius follow the same 6px/--app-border language as the alerts in
 * CSS-10B2; the focus ring is the usual additive keyboard-only outline.
 *
 * All color/geometry rules are scoped to the three theme-* bodies, so
 * Backend/Frontend — same stylesheet, no theme class — are untouched; the
 * unscoped `.close:focus-visible` is purely additive and falls back to
 * var(--primary) there.
 */
.theme-seller .aiz-table thead th,
.theme-supervisor .aiz-table thead th,
.theme-fieldbook .aiz-table thead th {
    background-color: var(--app-surface-alt, transparent);
    color: var(--app-ink, inherit);
    border-bottom-color: var(--app-border, #eceff7);
}

.theme-seller .modal-content,
.theme-supervisor .modal-content,
.theme-fieldbook .modal-content {
    border-radius: 6px;
    border-color: var(--app-border, rgba(20, 20, 35, .2));
}

.theme-seller .modal-content .modal-header,
.theme-supervisor .modal-content .modal-header,
.theme-fieldbook .modal-content .modal-header {
    border-bottom-color: var(--app-border, #ebedf2);
}

.modal-header .close:focus-visible {
    outline: 2px solid var(--app-focus, var(--primary));
    outline-offset: 2px;
}

/*
 * SECTION 6 - Entity cards (CSS-07A)
 *
 * First shared implementation of the generic "entity card" shell used by
 * Product, Invoice and Client listings (see documentation/ui_style_audit/
 * Roadmap_css.md, CSS-07A). The shell is purely structural: container,
 * header row, body and footer regions. It has zero knowledge of Wine,
 * Invoice, Product, Client, Plot or Process — domain colors, badges and
 * business rules stay in the calling Blade view.
 *
 * Consumers: resources/views/components/entity/card.blade.php,
 * header.blade.php, thumbnail.blade.php, meta-grid.blade.php.
 *
 * Overflow / dropdown fix (CSS-04B): the outer `.entity-card` uses
 * `overflow: visible` so a `.action-group` dropdown menu in the footer is
 * never clipped; rounded corners are instead applied per-region (on the
 * header's top corners and the footer's bottom corners), matching the
 * pattern already proven in the old invoice `card-styles.blade.php`.
 */
/*
 * Shell geometry (border, radius, header/body/footer padding, thumbnail
 * radius, top accent bar) updated to the values approved in the Wine
 * "Proposal D" local design-lab pilot (public/assets/design-proposals/
 * wine/proposal-d.css) as part of Wine D productionization (CSS-11): the
 * approved look no longer lives only behind Wine's local-only `?design=d`
 * preview, it is now the real shared `.entity-card` shell consumed by
 * Wine, Plot, Product, Invoice and Client alike. Domain colors/badges stay
 * out of this block, same as before.
 */
.entity-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #e9e9e9;
    border-radius: 3px 14px 3px 14px;
    /* Kept `visible`, NOT D's own `hidden`: proposal-d.css only ever loads
     * on the isolated Wine-D preview, whose footer dropdown was already
     * flattened into plain buttons in that same branch. Other real
     * `.entity-card` consumers (e.g. seller/invoice/partials/
     * invoice-item-card.blade.php) still open a `.dropdown-menu` from
     * inside the card and would get it clipped by `overflow: hidden` —
     * so the accent bar below carries its own matching top radius instead
     * of relying on the parent clipping it. */
    overflow: visible;
    margin-bottom: 1rem;
}

/* Top accent bar (CSS-11): a thin, theme-colored line that reads as part
 * of the card shell for every domain. Domains whose rows carry their own
 * sub-type color (e.g. Wine's tinto/blanco/rosado/must) override the
 * background via a `:has()` rule kept in that domain's own CSS section —
 * see SECTION 7 for Wine's overrides. Degrades to no bar at all on
 * browsers without :has() support (the card still reads correctly without
 * it, exactly as proposal-d.css documents). Radius matches the card's own
 * top corners directly (rather than via overflow clipping) so the base
 * shell can stay `overflow: visible`. */
.entity-card::before {
    content: "";
    display: block;
    height: 3px;
    border-radius: 3px 14px 0 0;
    background: var(--app-border, #e4e2ef);
}

.entity-card--hover-lift {
    transition: box-shadow .15s ease, transform .15s ease;
}

.entity-card--hover-lift:hover {
    box-shadow: 0 4px 14px rgba(0, 0, 0, .08);
    transform: translateY(-2px);
}

/* Cross-cutting: never let a hover-lift card jump around while a modal is
 * open behind it (e.g. a "More actions" dropdown trigger sitting under a
 * modal backdrop). Generic because it applies to any hover-lift card, not
 * just Invoice, where this was first observed. */
body.modal-open .entity-card--hover-lift:hover {
    transform: none;
}

.entity-card--accent-danger {
    border-left: 4px solid var(--danger, #dc3545);
}

.entity-card--accent-dark {
    border-left: 4px solid #495057;
}

.entity-card__header {
    background: #fff;
    padding: .55rem .85rem .4rem;
}

.entity-card__body {
    padding: .4rem .85rem .3rem;
    flex: 1 1 auto;
}

.entity-card__footer {
    background: var(--app-surface-alt, #f5f4fb);
    padding: .4rem .85rem .5rem;
    border-radius: 0 0 3px 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

@media (max-width: 767px) {
    .entity-card__header {
        padding: .6rem .75rem .4rem;
    }

    .entity-card__body {
        padding: .35rem .75rem .3rem;
    }

    .entity-card__footer {
        padding: .4rem .75rem .55rem;
        flex-direction: column;
        align-items: stretch;
    }
}

.entity-card__header-row {
    display: flex;
    align-items: center;
    gap: .55rem;
}

.entity-card__header-main {
    flex: 1 1 auto;
}

.entity-card__header-aside {
    flex: 0 0 auto;
    margin-left: auto;
}

.entity-card__thumb {
    flex: 0 0 auto;
}

.entity-card__thumbnail {
    object-fit: cover;
    display: block;
    border-radius: 3px 9px 3px 9px;
}

.entity-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.entity-list > .entity-card:last-child {
    margin-bottom: 0;
}

@media (max-width: 576px) {
    .entity-card__header-row {
        flex-wrap: wrap;
    }

    .entity-card__header-aside {
        margin-left: 0;
    }
}

/*
 * Invoice status pill shape, renamed from the pilot's original
 * `.status-badge` to `.invoice-status-badge` to avoid colliding with the
 * pre-existing, global `.status-badge.*` system (see core.css tokens +
 * custom-style.css), which is already used outside Invoice (e.g.
 * seller/containers/maintenance.blade.php) with different colors for the
 * same modifier names (e.g. "pending"). Because components.css loads after
 * custom-style.css app-wide, keeping the old name would have silently
 * changed maintenance's status colors too.
 *
 * Only the structural pill shape lives here (generic, reusable by any
 * future status pill). The actual color per state is domain-owned and
 * stays in resources/views/seller/invoice/partials/card-styles.blade.php,
 * per CSS-07A's "centralize structure, not color/state logic" rule for
 * badges.
 */
.invoice-status-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .3px;
}

/* =======================================================================
 * SECTION 7 - Wine domain, shared List/Show CSS (CSS-07B2B)
 * ===================================================================== */
/*
 * wine_table.blade.php (Wine List, CSS-07B2A) and wine_show_table.blade.php
 * (Wine Show, CSS-07B2B) are two independent Blade partials that each
 * render a wine's name/thumbnail/must-or-alcohol pill. Both used to carry
 * an identical copy of these four rules in their own local <style> block.
 * Centralized here once real duplication was confirmed, so a future change
 * doesn't have to be made twice.
 *
 * Values updated (CSS-11 Wine D productionization) to the colors/weights
 * approved in the Wine "Proposal D" local design-lab pilot (public/assets/
 * design-proposals/wine/proposal-d.css), which previously only reached the
 * page behind the local-only `?design=d` toggle. Wine's real listing no
 * longer depends on that toggle to show the approved look (see SECTION 14),
 * so these domain-color baselines are now the same approved values
 * everywhere `.wine-title`/`.badge-must`/`.pill-must` render (List + Show),
 * instead of List showing the approved amber Mosto color only in preview
 * and Show showing the old teal. Data/routes/logic untouched.
 *
 * Deliberately NOT included here: `.badge` (a bare, Bootstrap-colliding
 * class name). Both wine partials still define their own local `.badge`
 * override, because promoting it to this file would change the cursor/
 * margin of every plain `.badge` element site-wide, not just the wine
 * modal-trigger pills it was written for.
 */
:root {
    --wine-tinto: #4a0f1f;
    --wine-tinto-fg: #f6e6ea;
    --wine-blanco: #e8c468;
    --wine-blanco-fg: #3a2c05;
    --wine-rosado: #c94277;
    --wine-rosado-fg: #ffffff;
    --wine-must: #a3630a;
    --wine-must-fg: #fff8ec;
}

.wine-title {
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: -.01em;
}

/* UI-PASS-04B: vintage/añada is primary Wine data (unlike a generic
 * "subtitle") and must stand out clearly next to the name, not read as
 * muted secondary text. Wine-specific — Plot/Product have no equivalent
 * concept. */
.wine-vintage {
    font-size: .95rem;
    font-weight: 700;
    color: var(--app-primary, #5c1a2c);
    margin-left: .2rem;
}

.wine-thumb-shadow {
    box-shadow: 0 2px 8px rgba(18, 18, 26, .14);
}

.badge-must {
    background: var(--wine-must) !important;
    color: var(--wine-must-fg) !important;
}

.badge-tinto {
    background: var(--wine-tinto);
    color: var(--wine-tinto-fg);
}

.badge-blanco {
    background: var(--wine-blanco);
    color: var(--wine-blanco-fg);
}

.badge-rosado {
    background: var(--wine-rosado);
    color: var(--wine-rosado-fg);
}

.wine-alcohol-highlight--must {
    background: var(--wine-must-fg) !important;
    color: var(--wine-must) !important;
}

.pill-must {
    display: inline-block;
    background: var(--app-primary, #5c1a2c);
    color: #fff;
    font-weight: 700;
    border-radius: 3px 10px 3px 10px;
    padding: .2em .6em .1em .6em;
    box-shadow: none;
    line-height: 1;
    min-width: 44px;
    font-size: .8rem;
}

/*
 * UI-PASS-04A2: page-level title/card treatment from the approved Wine
 * design (proposal-d.css: `.aiz-titlebar h1.h3` + `.card`) was never ported
 * during CSS-11 productionization — only .entity-action/.entity-card were.
 * Reuses the existing Seller theme tokens (--app-primary/-soft/-border,
 * already the same values as proposal-d.css's --d-brand/-soft/-border) so
 * no new brand color is invented here. Scoped to .wine-page-header/
 * .wine-page-card (added only to seller/wine/index.blade.php) rather than
 * the bare `.aiz-titlebar h1.h3` / `.card` selectors, which are shared by
 * ~288 other Seller views and the generic Bootstrap card everywhere else —
 * this is a Wine-domain-only visual difference, not a shared-primitive gap.
 */
.wine-page-header h1.h3 {
    display: inline-block;
    color: var(--app-primary, #5c1a2c);
    font-weight: 800;
    letter-spacing: -.02em;
    padding-bottom: .3rem;
    border-bottom: 3px solid var(--app-primary, #5c1a2c);
}

.wine-page-card {
    border: 1px solid var(--app-border, #e6d3d8);
    border-radius: 4px 16px 4px 16px;
    box-shadow: none;
}

/* Accent bar (SECTION 6): Wine rows carry their own sub-type color via the
 * category badge that's already present in the card (data-driven, no
 * Blade change needed). Falls back to the generic neutral bar for rows
 * whose type badge isn't one of these four (or on browsers without
 * :has() support). */
.entity-card:has(.badge-tinto)::before {
    background: var(--wine-tinto);
}

.entity-card:has(.badge-blanco)::before {
    background: var(--wine-blanco);
}

.entity-card:has(.badge-rosado)::before {
    background: var(--wine-rosado);
}

.entity-card:has(.badge-must)::before {
    background: var(--wine-must);
}

/*
 * UI-PASS-04A5: the owner confirmed by eye that Wine's action buttons,
 * thumbnail, header, counter pills and mini-panels all render too small —
 * not a color/border defect (fixed in UI-PASS-04A4), a scale defect. The
 * properties below (.entity-action, .entity-card__thumbnail,
 * .entity-counter-pill, .entity-mini-panel*) are shared with Plot/Product,
 * so every override here is scoped under `.wine-page-card` (added only to
 * seller/wine/index.blade.php, same scoping already used above for
 * .wine-page-header/.wine-page-card) instead of changing the shared base
 * rules. This keeps Plot/Product at their current size — per explicit
 * instruction, those get the same scale only after Wine is approved.
 *
 * UI-PASS-04B follow-up: the owner then manually grew the thumbnail to
 * 100px and restructured the Información panel by hand (kept as-is, not
 * reverted). This pass pulls back the mini-panel/title font sizes by one
 * step (were reported as excessive at the previous size), adds header/
 * badge spacing, and — now that Wine's scale is approved — extends the
 * domain-agnostic rules (action buttons, thumbnail, counter pills,
 * mini-panel typography, header spacing) to `.plot-page-card` as well
 * (added to seller/plot/index.blade.php's card wrapper), so Plot consumes
 * the same shared values instead of a duplicated copy. Rules that are
 * genuinely Wine-only (`.wine-title`, `.wine-badges`) stay scoped to
 * `.wine-page-card` alone.
 */
.plot-page-card .action-group .entity-action {
    font-size: .68rem !important;
    min-width: 68px !important;
    max-width: 94px !important;
    padding: .4rem .45rem !important;
    gap: .2rem !important;
    max-height: 3.1rem !important;
    margin-right: 5px;
}

.plot-page-card .action-group .entity-action i {
    font-size: 1.3rem !important;
}

@media (max-width: 400px) {
    .plot-page-card .action-group .entity-action {
        max-width: none !important;
        width: 100% !important;
    }
}

.wine-page-card .entity-card__thumbnail,
.plot-page-card .entity-card__thumbnail {
    width: 100px !important;
    height: 100px !important;
}

.wine-page-card .wine-title {
    font-size: 1.1rem !important;
}

.wine-page-card .wine-badges .requestbadge {
    font-size: 12.5px !important;
    padding: 5px 14px !important;
}

.wine-page-card .entity-counter-pill,
.plot-page-card .entity-counter-pill {
    font-size: .8rem !important;
    padding: .32rem .65rem !important;
    gap: .4rem !important;
}

.wine-page-card .entity-counter-pill i,
.plot-page-card .entity-counter-pill i {
    font-size: 1rem !important;
}

.wine-page-card .entity-mini-panel__header,
.plot-page-card .entity-mini-panel__header {
    font-size: .7rem !important;
}

.wine-page-card .entity-mini-panel__icon,
.plot-page-card .entity-mini-panel__icon {
    width: 1.2rem !important;
    height: 1.2rem !important;
    font-size: .68rem !important;
}

.wine-page-card .entity-mini-panel__body,
.plot-page-card .entity-mini-panel__body {
    padding: .5rem .6rem !important;
}

.wine-page-card .entity-mini-panel__item,
.plot-page-card .entity-mini-panel__item {
    font-size: .78rem !important;
}

.wine-page-card .entity-mini-panel__label,
.plot-page-card .entity-mini-panel__label {
    font-size: .66rem !important;
}

.wine-page-card .entity-mini-panel__value,
.plot-page-card .entity-mini-panel__value {
    font-size: .78rem !important;
}

/*
 * UI-PASS-04B: header spacing — image/name separation was cramped once the
 * thumbnail grew to 100px. Shared with Plot (same thumbnail growth);
 * `.wine-badges-row` spacing stays Wine-only since Plot has no equivalent
 * badge rows.
 */
.wine-page-card .entity-card__header-row,
.plot-page-card .entity-card__header-row {
    gap: .9rem;
}

.wine-page-card .wine-badges-row {
    gap: .5em !important;
}

.wine-page-card .wine-badges-row--type {
    margin-top: .45rem !important;
}

.wine-page-card .wine-badges-row--meta {
    margin-top: .5rem !important;
}

/* Related-person row (Oenologist): small inline avatar + link, vertically
 * centered against the "Oenologist" label — see .entity-person-inline
 * (generic, SECTION further down) for the shared pattern definition. */
.wine-page-card .entity-person-inline__avatar {
    width: 24px !important;
    height: 24px !important;
}

/* =======================================================================
 * SECTION 8 - Viticulturist "show" KPI panel: static variant (CSS-08A / CSS-08B2)
 * ===================================================================== */
/*
 * viticulturist/show.blade.php (Seller/Supervisor/Fieldbook — Fieldbook
 * labels it "Farmer") each carried a byte-identical 38-line <style> block
 * for the KPI doughnut-chart card on the viticulturist detail page.
 * Centralized here once the three copies were confirmed identical via
 * diff. Only the show page's markup/route/translate() strings differ
 * between modules — those stay in each module's own show.blade.php.
 *
 * CSS-08B2: this section is now explicitly namespaced under
 * `.kpi-widget-static`, applied to the card-body wrapping the canvas +
 * kpiCheckboxList in the three show.blade.php files. Without that class
 * on an ancestor, none of the rules below apply to anything — they no
 * longer leak onto `#statsWidgetChart` / `.kpi-label` /
 * `.filter-label-disabled` elsewhere (viticulturist/index's floating
 * widget uses the separate `.kpi-widget-floating` namespace in Section 9;
 * sown/index reuses that same namespace; plot, harvest, wine_cellars,
 * yield-estimations and plot-audit still carry their own local, unscoped
 * <style> blocks and are unaffected either way). See Roadmap_css.md
 * CSS-08B2 for the fuga (leak) this fixes and CSS-08B1 for the interim
 * workaround it replaces.
 */
.kpi-widget-static #statsWidgetChart {
    width: 100% !important;
    max-width: 380px;
    min-width: 160px;
    aspect-ratio: 1 / 1;
    height: auto !important;
    max-height: 340px;
    min-height: 160px;
    display: block;
    margin: 1.5rem auto 0 auto;
    box-sizing: border-box;
    background: linear-gradient(135deg, #f3f4f6 0%, #e0f2fe 100%);
    border-radius: 1rem;
    box-shadow: 0 4px 18px rgba(52, 163, 153, 0.09);
    transition:
        box-shadow 0.25s cubic-bezier(.4, 0, .2, 1),
        background 0.25s cubic-bezier(.4, 0, .2, 1),
        max-width 0.2s,
        max-height 0.2s;
}

.kpi-widget-static #statsWidgetChart:hover,
.kpi-widget-static #statsWidgetChart:focus {
    box-shadow: 0 8px 32px rgba(52, 163, 153, 0.13);
    background: linear-gradient(135deg, #e0f2fe 0%, #f3f4f6 100%);
}

.kpi-widget-static .filter-label-disabled {
    text-decoration: line-through;
    opacity: 0.6;
    cursor: pointer;
}

.kpi-widget-static .kpi-label {
    cursor: pointer;
}

/* =======================================================================
 * SECTION 9 - KPI Stats Widget: floating/index variant (CSS-08B1)
 * ===================================================================== */
/*
 * viticulturist/index.blade.php (Seller/Supervisor/Fieldbook) each carried
 * a byte-identical 374-line <style> block for the floating, draggable KPI
 * stats widget (#statsWidget/#statsPanel/#statsWidgetChart) plus its
 * filter checkboxes and resize handle — the "floating/interactive" variant
 * flagged in Section 8's header comment as incompatible with the static
 * "show" card variant already centralized there.
 *
 * Scope: `.kpi-widget-floating` is added as an extra class directly on the
 * existing `#statsWidget` div — no markup restructuring, no ID renamed, no
 * JS hook touched (JS still uses getElementById for every id below).
 * Every selector that used to be bare in the three local <style> blocks is
 * now written as `.kpi-widget-floating <selector>`, so it cannot collide
 * with Section 8's bare selectors for the same ID/class names and cannot
 * leak onto any page that doesn't carry the wrapper class.
 *
 * CSS-08B1 originally added an explicit reset of background/border-radius/
 * box-shadow/transition (and their :hover/:focus) here, because Section 8's
 * bare `#statsWidgetChart` rule was unscoped and therefore also matched
 * this element. CSS-08B2 fixed that leak at the root by namespacing
 * Section 8 under `.kpi-widget-static`, so Section 8 no longer matches
 * anything outside that namespace — the reset became dead weight and was
 * removed. `.kpi-widget-static` and `.kpi-widget-floating` are now two
 * fully isolated namespaces regardless of file/section order.
 *
 * `.filter-modal` and `.overview-transition` from the original block were
 * dropped: confirmed dead (no consumer) in all three viticulturist/index
 * views. `.filter-label-disabled` was dropped too, on the assumption that
 * it was byte-identical to the rule already above in Section 8 and that
 * that rule was global.
 *
 * CSS-08C1 correction: CSS-08B2 later scoped Section 8's rule under
 * `.kpi-widget-static`, so it stopped matching anything under
 * `.kpi-widget-floating` — silently leaving every floating consumer's
 * "uncheck to dim/strike a filter label" JS (all of them toggle
 * `.filter-label-disabled` on the label unconditionally) without any
 * matching CSS. Restored below, scoped to this namespace, so the existing
 * JS in every current and future `.kpi-widget-floating` consumer has a
 * rule to apply again.
 *
 * This scope name is intentionally generic/reusable — not tied to Seller,
 * Viticulturist or Vinai — so a future CSS-08B pass can apply it to the
 * other files that still carry their own local copy of this same
 * floating-widget pattern. See Roadmap_css.md CSS-08B1.
 */
#statsWidget.kpi-widget-floating {
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 1050;
    display: flex;
    flex-direction: column-reverse;
    align-items: flex-end;
    animation: fadeInUp 0.3s;
}

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(40px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.kpi-widget-floating #statsPanel {
    margin-bottom: 10px;
    opacity: 0;
    pointer-events: none;
    transform: translateY(40px) scale(0.98);
    transition:
        opacity 0.3s cubic-bezier(.4, 0, .2, 1),
        transform 0.3s cubic-bezier(.4, 0, .2, 1),
        box-shadow 0.3s cubic-bezier(.4, 0, .2, 1),
        background 0.3s cubic-bezier(.4, 0, .2, 1),
        width 0.25s, height 0.25s, left 0.25s, top 0.25s;
    width: 400px;
    height: 540px;
    min-width: 320px;
    max-width: 90vw;
    right: 30px;
    bottom: 30px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.10);
    background: #fff;
    border-radius: 1rem;
    overflow: hidden;
    position: fixed;
    z-index: 9999;
    resize: none !important;
}

.kpi-widget-floating #statsPanel.open {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0) scale(1);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
    background: #fafbfc;
}

.kpi-widget-floating #statsPanel.expanded {
    width: 560px !important;
    min-width: 360px !important;
    max-width: 96vw !important;
    height: 640px !important;
    min-height: 360px !important;
    max-height: 86vh !important;
    left: 50vw !important;
    top: 50vh !important;
    right: auto !important;
    bottom: auto !important;
    transform: translate(-50%, -50%) !important;
    z-index: 10010 !important;
    position: fixed !important;
}

.kpi-widget-floating #statsWidgetChart {
    width: 100% !important;
    max-width: 600px;
    min-width: 0;
    height: 300px !important;
    max-height: 400px;
    display: block;
    margin: 0 auto;
    box-sizing: border-box;
}

.kpi-widget-floating #statsPanel.expanded #statsWidgetChart {
    height: 240px !important;
    max-height: 320px;
}

.kpi-widget-floating #openStatsWidget {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    font-size: 24px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition:
        box-shadow 0.2s cubic-bezier(.4, 0, .2, 1),
        background 0.2s cubic-bezier(.4, 0, .2, 1),
        transform 0.2s cubic-bezier(.4, 0, .2, 1);
}

.kpi-widget-floating #openStatsWidget:hover,
.kpi-widget-floating #openStatsWidget:focus {
    box-shadow: 0 8px 32px rgba(33, 150, 243, 0.15);
    background: #1976d2;
    transform: scale(1.07);
}

.kpi-widget-floating #statsPanel input,
.kpi-widget-floating #statsPanel button,
.kpi-widget-floating #statsPanel label {
    cursor: auto;
}

.kpi-widget-floating #statsPanel .btn-close {
    cursor: pointer;
}

.kpi-widget-floating #statsPanel.dragging .card-body,
.kpi-widget-floating #statsPanel.dragging .card-header,
.kpi-widget-floating #statsPanel.resizing .card-body,
.kpi-widget-floating #statsPanel.resizing .card-header {
    color: white
}

.kpi-widget-floating #statsPanel .drag-handle {
    cursor: move;
}

.kpi-widget-floating #statsPanel.resizing {
    box-shadow: 0 0 0 3px #888 inset;
}

.kpi-widget-floating #statsPanel:focus {
    outline: 2px solid #1976d2;
}

/*
 * CSS-12/13 seccion 21: la casilla de cada filtro del widget de KPIs llevaba
 * `style="margin-right:6px"` repetido en cada elemento de cada listado de
 * Seller, Supervisor y Fieldbook (22 copias solo en los dos ultimos). No
 * habia ninguna regla para `.filter-checkbox` en ningun sitio, asi que esta
 * recoge el mismo valor que ya tenian todos en linea: no cambia como se ve
 * ninguna pagina, solo deja de repetirse en el marcado.
 *
 * `.kpi-checkbox` es la misma casilla en las fichas de detalle (el widget de
 * KPIs de plot/show, viticulturist/show...), con el mismo margen repetido.
 */
.filter-checkbox,
.kpi-checkbox {
    margin-right: 6px;
}

.kpi-widget-floating .filter-label {
    cursor: pointer;
}

.kpi-widget-floating .filter-label-disabled {
    text-decoration: line-through;
    opacity: 0.6;
    cursor: pointer;
}

@media (max-width: 500px) {
    .kpi-widget-floating #statsPanel {
        min-width: 90vw;
        max-width: 98vw;
        border-radius: 0.7rem;
    }
}

.kpi-widget-floating .custom-resizer {
    width: 18px;
    height: 18px;
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 10001;
    border-radius: 0 0 8px 0;
    cursor: se-resize;
    transition: opacity 0.2s, cursor 0.2s;
    background: none;
    background-image: url("data:image/svg+xml;utf8,<svg width='18' height='18' xmlns='http://www.w3.org/2000/svg'><line x1='7' y1='18' x2='18' y2='7' stroke='%23888' stroke-width='2'/><line x1='11' y1='18' x2='18' y2='11' stroke='%23888' stroke-width='2'/><line x1='15' y1='18' x2='18' y2='15' stroke='%23888' stroke-width='2'/></svg>");
    background-repeat: no-repeat;
    background-position: 55% 55%;
    background-size: 85% 85%;
    pointer-events: auto;
}

.kpi-widget-floating .custom-resizer[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed !important;
    pointer-events: auto;
}

/* =======================================================================
 * SECTION 10 - Viticulturist index: card list layout (CSS-08B1)
 * ===================================================================== */
/*
 * `.viticulturist-card/-header/-thumb/-body/-footer` were removed: Seller,
 * Supervisor and Fieldbook now all render rows via
 * components/viticulturist/card.blade.php, which is built on the shared
 * entity-card/entity-header/entity-mini-panel/entity-action primitives
 * instead. `.viticulturist-list` stays (still used as the row wrapper by
 * all three migrated views). `.plot-mini-card`, `.plot-title`, `.plot-meta`,
 * `.plot-variety-*`, `.badge-sown` and `.plot-modal-variety-*` also stay:
 * they're reused verbatim by components/viticulturist/plot-row.blade.php.
 *
 * CSS-12/13 seccion 21: supervisor/plot/index, supervisor/harvest/index y
 * fieldbook/plot/index repetian `.plot-mini-card` y su `:hover` en un <style>
 * propio, byte a byte igual que las reglas de aqui abajo. Esas copias ya no
 * estan: la pagina las recibe de esta hoja. seller/plot/partials/_styles
 * conserva la suya (la seccion 2 no reabre migraciones de Seller) pero los
 * valores son los mismos, asi que no cambia como se ve nada.
 *
 * `.plot-list` NO sube aqui: en plot/index es una columna simple, pero en
 * sown/index es el panel con scroll del maestro-detalle. Mismo nombre, dos
 * cosas distintas; compartirlo cambiaria la segunda.
 */
.viticulturist-list {
    display: flex;
    flex-direction: column;
    gap: 1.2rem;
}

/* ---- Plots / Sowns ---- */
.plot-mini-card {
    background: #f8fafc;
    border: 1.5px solid #e4e7ef;
    border-radius: 11px;
    margin-bottom: 16px;
    padding: 18px 18px 10px 18px;
    box-shadow: 0 3px 13px -4px #e0e5f6;
    position: relative;
    transition: box-shadow 0.2s;
}

.plot-mini-card:hover {
    box-shadow: 0 6px 24px -4px #bac7e8;
}

/*
 * CSS-12/13 seccion 21: la miniatura de parcela la pinta el componente
 * compartido components/plot/card.blade.php, pero el color de relleno que se
 * ve mientras no hay imagen estaba escrito en el <style> de cada consumidor.
 * Es el mismo valor que ya tenian, aqui una sola vez.
 */
.plot-image-thumb {
    background: #f9fafc;
}

.plot-title {
    font-size: 1.08rem;
    font-weight: bold;
    color: #2a3240;
    display: flex;
    align-items: center;
    gap: 0.7em;
    margin-bottom: 5px;
}

.plot-meta {
    font-size: 0.93em;
    color: #607d8b;
    margin-bottom: 3px;
    display: flex;
    gap: 1.3em;
    flex-wrap: wrap;
}

.plot-variety-list {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 6px;
}

.plot-variety-card {
    background: #fff;
    border: 1px solid #d5d9e7;
    border-radius: 8px;
    min-width: 145px;
    padding: 8px 10px;
    font-size: 0.95em;
    box-shadow: 0 1px 6px #f0f3fc;
    transition: box-shadow 0.18s;
    margin-bottom: 4px;
    flex: 1 1 145px;
}

.plot-variety-card:hover {
    box-shadow: 0 4px 12px -3px #d7e2f3;
}

.plot-variety-title {
    font-weight: 600;
    color: #36596b;
    margin-bottom: 2px;
}

.plot-variety-meta {
    font-size: 0.97em;
    color: #607d8b;
    margin-bottom: 1px;
    display: flex;
    align-items: center;
    gap: 0.4em;
}

.badge-sown {
    background: #eaf6f1;
    color: #277063;
    font-weight: 500;
    padding: 2px 8px;
    border-radius: 13px;
    margin-left: 6px;
    font-size: 0.90em;
}

/* Modal para sowns */
.plot-modal-variety-list {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.plot-modal-variety-card {
    background: #fff;
    border: 1.3px solid #e0e6f3;
    border-radius: 9px;
    padding: 13px 15px 10px 13px;
    margin-bottom: 10px;
    width: 230px;
    min-width: 180px;
    box-shadow: 0 2px 10px -3px #e0e6f3;
}

.plot-modal-variety-title {
    font-weight: 600;
    color: #304356;
    margin-bottom: 2px;
}

.plot-modal-variety-meta {
    font-size: 0.98em;
    color: #6e8094;
    margin-bottom: 1px;
    display: flex;
    align-items: center;
    gap: 0.5em;
}

/* =======================================================================
 * SECTION 11 - KPI Stats Widget: native-resize floating variant (CSS-08C6)
 * =======================================================================
 * CSS-08B3 first documented that Plot Index's floating stats widget does
 * NOT follow the same contract as `.kpi-widget-floating` (Section 9): it
 * has no fade-in-up entrance animation, no `#statsPanel` opacity/transform
 * managed transition, and no `.open`/`.expanded` position-and-size
 * override - visibility is toggled directly via inline `style.display` in
 * JS, and the panel keeps native browser `resize: both; overflow: auto;`
 * (set inline in the markup) instead of the managed variant's fixed
 * width/height and disabled `resize: none`.
 *
 * CSS-08C6 reconfirmed this fork still holds - the KPI CSS is byte-for-
 * byte identical across Seller/Supervisor/Fieldbook Plot Index, and was
 * diffed selector-by-selector against Section 9 - and formalizes it as
 * its own named variant instead of forcing Plot onto the managed
 * contract, which CSS-08B3 already ruled out as a behavior change (it
 * would add an entrance animation, remove native resize, and switch
 * open/close from display toggling to opacity/transform).
 *
 * `.kpi-widget-floating-native-resize` reproduces Plot's current behavior
 * exactly; it is not an improvement or a redesign. Which floating variant
 * (if any) becomes the single standard is a CSS-09 decision.
 *
 * Consumers: seller/plot/index.blade.php (via partials/_styles.blade.php),
 * supervisor/plot/index.blade.php, fieldbook/plot/index.blade.php.
 */
#statsWidget.kpi-widget-floating-native-resize {
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 1050;
    display: flex;
    flex-direction: column-reverse;
}

.kpi-widget-floating-native-resize #statsWidgetChart {
    width: 100% !important;
    max-width: 600px;
    min-width: 0;
    height: 300px !important;
    max-height: 400px;
    display: block;
    margin: 0 auto;
    box-sizing: border-box;
}

.kpi-widget-floating-native-resize #statsPanel.expanded #statsWidgetChart {
    height: 240px !important;
    max-height: 320px;
}

.kpi-widget-floating-native-resize #openStatsWidget {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    font-size: 24px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition:
        box-shadow 0.2s cubic-bezier(.4, 0, .2, 1),
        background 0.2s cubic-bezier(.4, 0, .2, 1),
        transform 0.2s cubic-bezier(.4, 0, .2, 1);
}

.kpi-widget-floating-native-resize #openStatsWidget:hover,
.kpi-widget-floating-native-resize #openStatsWidget:focus {
    box-shadow: 0 8px 32px rgba(33, 150, 243, 0.15);
    background: #1976d2;
    transform: scale(1.07);
}

.kpi-widget-floating-native-resize #statsPanel input,
.kpi-widget-floating-native-resize #statsPanel button,
.kpi-widget-floating-native-resize #statsPanel label {
    cursor: auto;
}

.kpi-widget-floating-native-resize #statsPanel .btn-close {
    cursor: pointer;
}

.kpi-widget-floating-native-resize #statsPanel.dragging .card-body,
.kpi-widget-floating-native-resize #statsPanel.dragging .card-header,
.kpi-widget-floating-native-resize #statsPanel.resizing .card-body,
.kpi-widget-floating-native-resize #statsPanel.resizing .card-header {
    color: white
}

.kpi-widget-floating-native-resize #statsPanel .drag-handle {
    cursor: move;
}

.kpi-widget-floating-native-resize #statsPanel.resizing {
    box-shadow: 0 0 0 3px #888 inset;
}

.kpi-widget-floating-native-resize #statsPanel:focus {
    outline: 2px solid #1976d2;
}

.kpi-widget-floating-native-resize .filter-label {
    cursor: pointer;
}

.kpi-widget-floating-native-resize .filter-label-disabled {
    text-decoration: line-through;
    opacity: 0.6;
    cursor: pointer;
}

@media (max-width: 500px) {
    .kpi-widget-floating-native-resize #statsPanel {
        min-width: 90vw;
        max-width: 98vw;
        border-radius: 0.7rem;
    }
}

.kpi-widget-floating-native-resize .custom-resizer {
    width: 18px;
    height: 18px;
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 10001;
    border-radius: 0 0 8px 0;
    cursor: se-resize;
    transition: opacity 0.2s, cursor 0.2s;
    background: none;
    background-image: url("data:image/svg+xml;utf8,<svg width='18' height='18' xmlns='http://www.w3.org/2000/svg'><line x1='7' y1='18' x2='18' y2='7' stroke='%23888' stroke-width='2'/><line x1='11' y1='18' x2='18' y2='11' stroke='%23888' stroke-width='2'/><line x1='15' y1='18' x2='18' y2='15' stroke='%23888' stroke-width='2'/></svg>");
    background-repeat: no-repeat;
    background-position: 55% 55%;
    background-size: 85% 85%;
    pointer-events: auto;
}

.kpi-widget-floating-native-resize .custom-resizer[aria-disabled="true"] {
    opacity: 0.45;
    cursor: not-allowed !important;
    pointer-events: auto;
}

/* =======================================================================
 * SECTION 12 - Entity list state tabs (UI-PASS-01)
 * ======================================================================= */
/*
 * Generic "Active/Archived" style tab nav for a paginated entity listing
 * that switches state via a GET query param (`?state=archived`) rather than
 * client-side tab panes — each tab is a real link so search/filters/sort/
 * pagination all round-trip through the server unchanged. First consumer:
 * the Plot listing (Seller/Supervisor/Fieldbook), unifying what used to be
 * three separate "Parcelas archivadas" sidenav pages into one listing.
 *
 * Colors come from the existing per-module theme tokens set by
 * theme-seller/theme-supervisor/theme-fieldbook (modules/*.css, CSS-10A:
 * --app-primary, --app-primary-soft, --app-border, --app-muted) so this
 * works identically under all three themes with zero new theme variables.
 *
 * Consumers: resources/views/components/entity/tabs.blade.php.
 */
.entity-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    border-bottom: 1px solid var(--app-border, #e9e9e9);
    margin-bottom: 1rem;
}

.entity-tabs__link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .5rem .9rem;
    border-radius: 6px 6px 0 0;
    border: 1px solid transparent;
    border-bottom: none;
    color: var(--app-muted, #6c757d);
    font-size: .95rem;
    font-weight: 500;
    text-decoration: none;
    margin-bottom: -1px;
}

.entity-tabs__link:hover {
    color: var(--app-primary, #495057);
    text-decoration: none;
}

.entity-tabs__link--active {
    background: var(--app-primary-soft, #f1f3f5);
    border-color: var(--app-border, #e9e9e9);
    color: var(--app-primary, #212529);
}

.entity-tabs__count {
    font-weight: 600;
}

@media (max-width: 576px) {
    .entity-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .entity-tabs__link {
        flex: 0 0 auto;
        white-space: nowrap;
    }
}

/*
 * SECTION 12b - Listing "add" CTA (UI-PASS-05)
 *
 * A listing page is a STACK of vertical blocks, not a horizontal toolbar:
 *
 *     page header (title left / help right)
 *     (+)            <- .entity-cta, centred on the page content
 *     tabs           <- .entity-tabs, owner of the bottom rule
 *     filters        <- .entity-filters, as many as the page needs
 *     listing
 *
 * The earlier .entity-toolbar put the tabs and the CTA in one row, which pushed
 * the "+" to the right and tied it to the tabs' bottom rule. That row was the
 * wrong concept and is gone: there is no shared toolbar class any more.
 *
 * The CTA itself is the historical AIZ "add" tile, kept as it still renders on
 * supervisor/yield-estimations: a white rounded box that lifts on hover
 * (shadow-sm + hov-shadow-lg + has-transition), a 60px bg-secondary circle with
 * the las la-plus la-3x glyph, and the action name under it. bg-secondary and
 * text-primary already resolve per module through --secondary/--primary,
 * remapped by theme-seller/supervisor/fieldbook (modules/*.css, CSS-10A), so the
 * tile takes each module's colour with no module CSS.
 *
 * What this section adds is only what the tile could not do by itself: centre it
 * on the page instead of sitting in a col-md-4 grid cell, cap its width so it
 * stays a button and not a banner, and give it a keyboard focus ring (the anchor
 * is the focusable element, the visible box is the child tile).
 *
 * Consumers: resources/views/components/entity/state-tabs.blade.php.
 */
.entity-cta {
    display: flex;
    justify-content: center;
    margin: 0 0 1rem;
}

.entity-cta__button {
    display: block;
    width: 100%;
    max-width: 320px;
    text-decoration: none;
}

.entity-cta__button:hover,
.entity-cta__button:focus {
    text-decoration: none;
}

.entity-cta__button:focus-visible {
    outline: none;
}

.entity-cta__button:focus-visible .entity-cta__tile {
    outline: 2px solid var(--app-focus, #9c3a52);
    outline-offset: 3px;
}

/*
 * CSS-12: a few listings genuinely have more than one "add" - the harvest
 * survey family offers start / start-mid / mid / end, and the Fieldbook farmer
 * list offers own / shared by the supervisor / shared by the commercial
 * partner. They are still the same tile and still the same block of the stack,
 * so this is a container for N <x-entity.cta>, not a second CTA.
 *
 * Without it each .entity-cta is its own centred flex row and four of them
 * become four stacked banners. Here they share one centred row, keep the 320px
 * cap each, and wrap onto the next line when they do not fit - which is what
 * puts them one per line on a phone, still centred.
 */
.entity-cta-group {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: stretch;
    gap: 1rem;
    margin: 0 0 1rem;
}

.entity-cta-group .entity-cta {
    flex: 0 1 320px;
    margin: 0;
}

/*
 * SECTION 12c - Listing filter bar (UI-PASS-05)
 *
 * Between the tabs and the listing. Holds whatever a page needs - nothing, one
 * search box, or five filters plus a submit - so it wraps instead of assuming a
 * single wide search input. Children keep a sane minimum and grow to share the
 * row; the trailing submit/reset stay their natural size at the end.
 *
 * Consumers: seller/product/products/index.blade.php.
 */
.entity-filters {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .65rem;
    padding: 0 0 1rem;
}

.entity-filters > .form-control,
.entity-filters > .entity-filters__field {
    flex: 1 1 180px;
    min-width: 160px;
    min-height: 42px;
}

.entity-filters > .entity-filters__field--wide {
    flex: 2 1 230px;
}

.entity-filters > .btn {
    flex: 0 0 auto;
}

/*
 * SELLER-UI-ALIGN-01: on Seller pages that open with a title band, the
 * contextual-help button sits in that band (right, level with the title)
 * instead of taking its own row above the title (the row collapses to
 * zero height and the button overflows into the title band). Pages without a title band
 * keep the original standalone row.
 */
.theme-seller .contextual-help-row:has(~ .aiz-titlebar) {
    height: 0;
    margin: 0 !important;
    position: relative;
    z-index: 2;
}

/* =======================================================================
 * SECTION 13 - Entity mini-panels, status chips, counters, text actions
 * and archive-as-button (UI-PASS-02)
 * ======================================================================= */
/*
 * Generalizes, into production CSS, the visual language proven in the
 * Wine "Proposal D" local design-lab pilot (public/assets/design-proposals/
 * wine/proposal-d.css, fixed as "Seller visual reference v1" per
 * Roadmap_css.md CSS-09D5) so it can be reused, unmodified, by any domain
 * built on <x-entity.card> — first consumer: Plot (Seller/Supervisor/
 * Fieldbook). Proposal D itself is untouched; nothing here changes Wine.
 *
 * Two separate color layers, kept deliberately independent (do not merge
 * them):
 *   1. Module identity -> var(--app-primary/--app-primary-soft/--app-border)
 *      from modules/{seller,supervisor,fieldbook}.css (CSS-10A). Drives
 *      mini-panel icon accents, counter pills, the header CTA and the
 *      "active" status chip, so the exact same markup reads burgundy,
 *      blue or green purely from the body's .theme-* class.
 *   2. Action semantics -> the --entity-action-* tokens below. Fixed,
 *      theme-independent: the same conceptual action (edit, view, ...)
 *      must always carry the same color regardless of which module or
 *      theme renders it (task requirement: "no fiesta de colores").
 */
:root {
    /* CSS-11 Wine D productionization: these were built during UI-PASS-02
     * as approximations of Proposal D, before the real proposal-d.css had
     * been directly re-verified value-by-value. `edit` already matched;
     * `view`, `composition`, `doc`, `history` and `archive` are corrected
     * here to D's real, owner-approved hex. `map` has no D equivalent
     * (Plot-only action) and is left as-is. `link`, `process` and the
     * reserved `danger` category are new, added to match D's real set. */
    --entity-action-edit: #2563a8;
    --entity-action-edit-soft: #e7f0f8;
    --entity-action-view: #3f7a74;
    --entity-action-view-soft: #e9f3f2;
    --entity-action-composition: #2f8f5b;
    --entity-action-composition-soft: #e7f5ee;
    --entity-action-map: #0e7490;
    --entity-action-map-soft: #e3f4f7;
    --entity-action-doc: #5b4b9e;
    --entity-action-doc-soft: #efecf8;
    --entity-action-link: #1f8a99;
    --entity-action-link-soft: #e5f3f5;
    --entity-action-process: #b5711f;
    --entity-action-process-soft: #faf1e1;
    --entity-action-history: #5b6675;
    --entity-action-history-soft: #eef0f2;
    --entity-action-archive: #8a5a24;
    --entity-action-archive-soft: #f4ece0;
    --entity-action-danger: #c0334a;
    --entity-action-danger-soft: #fbe6ea;
}

/* --- Mini panel: compact header + 2-col label/value grid. Geometry
 * realigned to Proposal D's real values (CSS-11). --- */
.entity-mini-panel {
    background: #fff;
    border: 1px solid var(--app-border, #e9e9e9);
    border-radius: 3px 10px 3px 10px;
    overflow: hidden;
    margin-bottom: .35rem;
}

.entity-mini-panel:last-child {
    margin-bottom: 0;
}

.entity-mini-panel + .entity-mini-panel {
    margin-top: 0;
}

.entity-mini-panel__header {
    display: flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .5rem;
    background: var(--app-surface-alt, #f5f4fb);
    border-bottom: 1px solid var(--app-border, #e9e9e9);
    font-size: .64rem;
    font-weight: 700;
    color: var(--app-muted, #6f6f7d);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.entity-mini-panel__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--app-primary-soft, #f1f3f5);
    color: var(--app-primary, #495057);
    font-size: .62rem;
    flex: none;
}

/* UI-PASS-04B: title grows to fill the header row so a header that only
 * carries icon + title (no extra slot) doesn't visually collapse. */
.entity-mini-panel__title {
    flex: 1 1 auto;
}

.entity-mini-panel__body {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: .6rem;
    row-gap: .25rem;
    padding: .4rem .5rem;
}

.entity-mini-panel__body--stack {
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

/*
 * CSS-12: some panels list several records instead of one record's fields -
 * the Supervisor winery card shows the last four plots, containers and
 * harvests of each winery. Each record needs its own little stack of
 * label/value rows, and those stacks are what occupy the grid cells, so the
 * cell is the group and the items inside it run vertically.
 *
 * Without this the items of all four records land in the same two columns
 * and interleave, which is why that page carried its own sub-card CSS.
 */
.entity-mini-panel__group {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

.entity-mini-panel__group-title {
    font-size: .64rem;
    font-weight: 700;
    color: var(--app-muted, #6f6f7d);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.entity-mini-panel__item {
    min-width: 0;
    display: flex;
    justify-content: flex-start;
    align-items: baseline;
    gap: .3rem;
    font-size: .76rem;
    white-space: nowrap;
    overflow: hidden;
}

/* UI-PASS-04B generic modifiers: any mini-panel field can opt into a
 * vertically-centered row (e.g. one containing an avatar) or a multiline
 * value (long free text — no truncation, natural vertical growth). Neither
 * is Wine-specific: Product's description or Plot's supervisor row need
 * the same behavior. */
.entity-mini-panel__item--center {
    align-items: center;
}

.entity-mini-panel__item--multiline {
    flex-direction: column;
    align-items: flex-start;
    gap: .15rem;
    white-space: normal;
    overflow: visible;
}

.entity-mini-panel__item--multiline .entity-mini-panel__value {
    display: block;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

.entity-mini-panel__label {
    display: inline;
    font-size: .64rem;
    color: var(--app-muted, #6f6f7d);
    text-transform: uppercase;
    letter-spacing: .04em;
    font-weight: 700;
    margin-bottom: 0;
}

.entity-mini-panel__value {
    display: inline;
    font-size: .76rem;
    color: #12121a;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (max-width: 576px) {
    .entity-mini-panel__body {
        grid-template-columns: 1fr;
    }
}

/* --- Counter pills: compact clickable icon+text+count. Geometry
 * realigned to Proposal D's real values (CSS-11). --- */
.entity-counters-row {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    margin: .35rem 0;
}

.entity-counter-pill {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .18rem .5rem;
    border-radius: 3px 8px 3px 8px;
    border: 1px solid var(--app-border, #e9e9e9);
    background: var(--app-surface-alt, #f5f4fb);
    color: var(--app-primary-hover, #495057);
    font-size: .68rem;
    font-weight: 700;
    text-decoration: none;
    line-height: 1;
    margin-right: 10px;
}

a.entity-counter-pill:hover {
    background: var(--app-primary-soft, #f6e8ea);
    border-color: var(--app-border, #adb5bd);
    color: var(--app-primary, #495057);
    text-decoration: none;
}

.entity-counter-pill__icon {
    color: var(--app-primary, #868e96);
}

.entity-counter-pill__count {
    font-weight: 700;
}

/* --- Status chip: phenology / operational state read as a STATE.
 * Geometry realigned to Proposal D's real values (CSS-11). --- */
.entity-status-chip {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .25rem .4rem;
    border-radius: 3px 8px 3px 8px;
    font-size: .74rem;
    font-weight: 700;
    background: #eeeef0;
    color: #52525b;
    border: 1px solid transparent;
}

.entity-status-chip i {
    font-size: .95rem;
    flex: none;
}

.entity-status-chip--active {
    background: var(--app-primary-soft, #eaf1fa);
    color: var(--app-primary, #2563a8);
}

.entity-status-chip--ready {
    background: var(--entity-action-composition-soft);
    color: var(--entity-action-composition);
}

.entity-status-chip--idle {
    background: var(--app-surface-alt, #f1f3f5);
    color: var(--app-muted, #868e96);
}

.entity-status-chip__date {
    font-weight: 500;
    opacity: .85;
}

/* --- Text actions: icon-over-label compact pill, replaces circular
 * icon-only buttons and dropdown "..." menus. Meant to sit inside the
 * existing generic .action-group (SECTION 3 / CSS-04A) layout container.
 *
 * CSS-11 Wine D productionization: geometry corrected from a horizontal
 * icon+label chip (an UI-PASS-02 approximation) to Proposal D's real,
 * owner-approved vertical icon-over-label pill — this was the single
 * largest reason Plot's action buttons didn't visually match Wine D even
 * though both nominally used "the entity-action standard". `!important`
 * kept on layout properties for the same reason proposal-d.css uses it:
 * the AIZ seller/supervisor/fieldbook theme's `.btn-icon`/`.btn-circle`/
 * `.btn-sm.btn-icon` rules can otherwise win individual properties (e.g.
 * padding:0 or flex-direction:row) over a plain unqualified selector. --- */
.action-group .entity-action,
.entity-action {
    display: inline-flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: .15rem !important;
    width: auto !important;
    height: auto !important;
    min-width: 54px !important;
    max-width: 78px !important;
    min-height: 0 !important;
    padding: .3rem .25rem !important;
    border-radius: 3px 9px 3px 9px !important;
    font-size: .58rem !important;
    font-weight: 600 !important;
    line-height: 1.1 !important;
    text-align: center !important;
    white-space: normal !important;
    overflow: hidden !important;
    max-height: 2.4rem !important;
    border: 1px solid transparent !important;
    background: #f1f3f5 !important;
    color: #495057 !important;
}

.entity-action i {
    font-size: 1.15rem !important;
    width: auto !important;
    margin: 0 !important;
}

.entity-action span {
    display: inline-block !important;
    margin-top: .1rem !important;
}

/*
 * UI-PASS-04A4: proposal-d.css defined every one of these color modifiers
 * as `.action-group .wine-action--X` (compound selector, specificity
 * 0,0,2,0) — never as a bare single class. Porting to `.entity-action--X`
 * dropped the `.action-group` prefix and fell back to a bare class
 * (specificity 0,0,1,0), i.e. the SAME specificity as the AIZ theme's own
 * `.btn-soft-info`/`.btn-soft-danger`/etc. utility classes already present
 * on these same elements (see wine_table.blade.php's button markup). At
 * equal specificity the winner depends on stylesheet load order alone,
 * which made these rules fragile — `--history` had already been patched
 * with `!important` as a one-off fix for exactly this, while the other 9
 * modifiers were left on the fragile bare-class form and lost the border/
 * background/color in practice. Restored here: the compound
 * `.action-group .entity-action--X` selector (matching D's real
 * specificity) plus `!important`, applied to all 10 modifiers so none of
 * them depend on load order again. The bare `.entity-action--X` selector is
 * kept alongside it for the one confirmed consumer that renders it outside
 * `.action-group` (Plot's "view all varieties" button in
 * seller/plot/partials/_plot_card.blade.php).
 */
.action-group .entity-action--edit,
.entity-action--edit {
    color: var(--entity-action-edit) !important;
    background: var(--entity-action-edit-soft) !important;
    border-color: var(--entity-action-edit) !important;
}

.action-group .entity-action--view,
.entity-action--view {
    color: var(--entity-action-view) !important;
    background: var(--entity-action-view-soft) !important;
    border-color: var(--entity-action-view) !important;
}

.action-group .entity-action--composition,
.entity-action--composition {
    color: var(--entity-action-composition) !important;
    background: var(--entity-action-composition-soft) !important;
    border-color: var(--entity-action-composition) !important;
}

.action-group .entity-action--map,
.entity-action--map {
    color: var(--entity-action-map) !important;
    background: var(--entity-action-map-soft) !important;
    border-color: var(--entity-action-map) !important;
}

.action-group .entity-action--doc,
.entity-action--doc {
    color: var(--entity-action-doc) !important;
    background: var(--entity-action-doc-soft) !important;
    border-color: var(--entity-action-doc) !important;
}

.action-group .entity-action--link,
.entity-action--link {
    color: var(--entity-action-link) !important;
    background: var(--entity-action-link-soft) !important;
    border-color: var(--entity-action-link) !important;
}

.action-group .entity-action--process,
.action-group .entity-action--transfer,
.entity-action--process,
.entity-action--transfer {
    color: var(--entity-action-process) !important;
    background: var(--entity-action-process-soft) !important;
    border-color: var(--entity-action-process) !important;
}

.action-group .entity-action--history,
.entity-action--history {
    color: var(--entity-action-history) !important;
    background: var(--entity-action-history-soft) !important;
    border-color: var(--entity-action-history) !important;
}

.action-group .entity-action--danger,
.entity-action--danger {
    color: var(--entity-action-danger) !important;
    background: var(--entity-action-danger-soft) !important;
    border-color: var(--entity-action-danger) !important;
}

.entity-action:hover {
    filter: brightness(0.94) !important;
}

/* --- Archive as a persistent button, never a switch --- */
.action-group .entity-action--archive,
.entity-action--archive {
    background: var(--entity-action-archive-soft) !important;
    color: var(--entity-action-archive) !important;
    border-color: var(--entity-action-archive) !important;
}

.action-group .entity-action--archive.is-active,
.entity-action--archive.is-active {
    background: var(--entity-action-archive) !important;
    color: #fff !important;
    border-color: var(--entity-action-archive) !important;
}

@media (max-width: 400px) {
    .action-group {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: .3rem;
        width: 100%;
        justify-content: stretch;
    }

    .action-group .entity-action {
        max-width: none !important;
        width: 100% !important;
    }
}

/* --- Compact plantation row: replaces the oversized .plot-mini-card
 * duplicated across the three role-specific index files with one dense,
 * scannable row that fits inside <x-entity.card>'s body. --- */
.entity-plantation-list {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.entity-plantation-row {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: flex-start;
    padding: .6rem .75rem;
    border: 1px solid var(--app-border, #e9e9e9);
    border-radius: 8px;
    background: #fff;
}

.entity-plantation-row__thumb {
    width: 44px;
    height: 44px;
    border-radius: 6px;
    object-fit: cover;
    border: 1.5px solid var(--app-border, #e3e6ef);
    flex: 0 0 auto;
    background: #f9fafc;
}

.entity-plantation-row__main {
    min-width: 0;
    flex: 1 1 auto;
}

.entity-plantation-row__title {
    font-weight: 700;
    font-size: .88rem;
    color: #343a40;
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
}

.entity-plantation-row__meta {
    font-size: .78rem;
    color: var(--app-muted, #868e96);
    display: flex;
    flex-wrap: wrap;
    gap: .1rem .75rem;
    margin-top: 2px;
}

.entity-plantation-row__state {
    flex: 0 0 auto;
    text-align: right;
}

@media (max-width: 576px) {
    .entity-plantation-row__state {
        width: 100%;
        text-align: left;
        margin-top: .35rem;
    }
}

/* --- UI-PASS-04C: a plantation row's own action list + related person
 * (viticultor), on a full-width line below thumb/main/state so 5 compact
 * actions never fight the title/meta for space. The dashed rule is scoped
 * to this footer only — it is not the plantation row's own top edge (the
 * row keeps its normal 4-side border above), so it does not reproduce the
 * earlier "row loses its top border" regression. --- */
.entity-plantation-row__footer {
    flex: 0 0 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: .5rem;
    padding-top: .5rem;
    border-top: 1px dashed var(--app-border, #e9e9e9);
}

.entity-plantation-row__actions {
    display: flex;
    align-items: center;
    gap: .3rem;
    flex-wrap: wrap;
}

.entity-plantation-row__person {
    min-width: 0;
}

/* --- Compact action for dense contexts (a plantation row can carry up to 5
 * actions inside ~38% of the card's width).
 *
 * CSS-11: this used to be a 28px circle with `span { display: none }`, which
 * broke the two rules the Visual Standard states outright — §3 forbids
 * "iconos circulares aislados", and the responsive section forbids hiding an
 * action's text at any width ("solo puede envolver"). It was the one place in
 * the system where an action had no visible label.
 *
 * So compact now means NARROWER, not label-less: same shape, same semantic
 * colours, same icon-over-text stacking as every other action, just a smaller
 * footprint. Five of them no longer fit on one line in a 38% column, which is
 * fine — .entity-plantation-row__actions already wraps, and wrapping is what
 * the standard says to do. --- */
.entity-action--compact,
.action-group .entity-action--compact {
    min-width: 42px !important;
    max-width: 62px !important;
    padding: .15rem .2rem !important;
}

.entity-action--compact i {
    font-size: .8rem !important;
}

/* --- Parcela / Plantaciones proportion (~62/38, the closest precise split
 * to the requested 60-65/35-40 — no Bootstrap col-md-X fraction lands in
 * that range). Generic layout, not Plot-specific: any entity card pairing
 * its own info with a related sub-entity list can reuse it. --- */
.entity-card__body-split {
    display: flex;
    flex-wrap: wrap;
}

.entity-card__body-split__primary {
    flex: 0 0 62%;
    max-width: 62%;
    padding-right: 1rem;
    border-right: 1px solid var(--app-border, #e9e9e9);
}

.entity-card__body-split__related {
    flex: 0 0 38%;
    max-width: 38%;
    padding-left: 1rem;
}

@media (max-width: 767px) {
    .entity-card__body-split__primary,
    .entity-card__body-split__related {
        flex: 0 0 100%;
        max-width: 100%;
        padding-left: 0;
        padding-right: 0;
        border-right: none;
    }

    .entity-card__body-split__related {
        margin-top: 1rem;
    }
}

/* --- Empty state, generalized from Wine's compact block variant.
 * Geometry realigned to Proposal D's real values (CSS-11): compact but
 * not bare, no 100-120px of air for a single sentence. --- */
.entity-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    padding: .85rem 0;
    margin-bottom: 0;
    text-align: center;
    font-size: .85rem;
    color: var(--app-muted, #868e96);
}

.entity-empty-state i {
    font-size: 1.35rem;
    margin-bottom: .3rem;
    color: var(--app-border, #ced4da);
}

/* Block variant (CSS-11): icon + text inline, soft background + border —
 * replaces a bare Bootstrap alert-info for an empty state that sits
 * inside a modal body rather than centered on its own. */
.entity-empty-state--block {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: .6rem;
    background: var(--app-surface-alt, #f5f4fb);
    border: 1px solid var(--app-border, #e4e2ef);
    border-radius: 3px 10px 3px 10px;
    padding: .6rem .8rem;
    color: #12121a;
    font-size: .82rem;
    text-align: left;
}

.entity-empty-state--block i {
    font-size: 1.3rem;
    margin-bottom: 0;
    color: var(--app-primary, #5c1a2c);
}

/* --- Compact modal language shared with Wine's approved pattern:
 * neutral header, theme accent line, no artificial gaps. Scoped to
 * `.entity-modal-content` (an opt-in class added alongside Bootstrap's own
 * `.modal-content`) rather than overriding the bare Bootstrap selectors,
 * so plain modals elsewhere in the app are unaffected. --- */
.entity-modal-content {
    border: 0;
    border-radius: 3px 14px 3px 14px;
    overflow: hidden;
}

.entity-modal-content .modal-header {
    background: var(--app-surface, #fff);
    border-bottom: 1px solid var(--app-border, #e9e9e9);
    padding: .65rem 1rem;
    position: relative;
}

.entity-modal-content .modal-header::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--app-primary, #6c757d);
}

.entity-modal-content .modal-title {
    font-weight: 800;
    font-size: 1rem;
    color: #12121a;
}

.entity-modal-content .modal-header .close {
    margin: -.2rem -.2rem -.2rem auto;
    padding: 0;
    width: 1.75rem;
    height: 1.75rem;
    line-height: 1.75rem;
    text-align: center;
    border-radius: 50%;
    opacity: .55;
    transition: background-color .15s ease, opacity .15s ease;
}

.entity-modal-content .modal-header .close:hover {
    opacity: 1;
    background: rgba(0, 0, 0, .06);
}

.entity-modal-content .modal-body {
    padding: 1rem;
}

.entity-modal-content .modal-body .table-responsive {
    margin: 0;
}

.entity-modal-content .modal-body table.table {
    margin-bottom: 0;
    font-size: .84rem;
}

.entity-modal-content .modal-body table.table th,
.entity-modal-content .modal-body table.table td {
    padding: .5rem .6rem;
    vertical-align: middle;
}

.entity-modal-content .modal-body table.thead-light th {
    color: var(--app-muted, #6f6f7d);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    font-size: .76rem;
    border-top: none;
    border-bottom: 2px solid var(--app-border, #e4e2ef);
}

.entity-modal-content .modal-body table.table-striped tbody tr:nth-of-type(odd) {
    background-color: var(--app-primary-soft, #f6e8ea);
}

.entity-modal-content .modal-body table.table-hover tbody tr:hover {
    background-color: var(--app-border, #e6d3d8);
}

.entity-modal-content .modal-footer {
    padding: .6rem 1rem;
    border-top: 1px solid var(--app-border, #e9e9e9);
}

.entity-modal-content .modal-footer .btn {
    padding: .4rem 1.1rem;
    font-size: .82rem;
    font-weight: 700;
    border-radius: 3px 10px 3px 10px;
    box-shadow: none;
}

/* --- History-style event badge: 4 semantic buckets (positive/negative/
 * info/neutral) instead of many near-random inline hues, reusing the
 * shared action-color tokens so it stays visually consistent with the
 * rest of the action/status system. --- */
.entity-history-badge {
    width: auto !important;
    padding: .3rem .65rem !important;
    font-weight: 700;
    font-size: .72rem;
}

.entity-history-badge--positive {
    background: var(--entity-action-composition-soft);
    color: var(--entity-action-composition);
}

.entity-history-badge--negative {
    background: var(--entity-action-danger-soft);
    color: var(--entity-action-danger);
}

.entity-history-badge--info {
    background: var(--entity-action-link-soft);
    color: var(--entity-action-link);
}

.entity-history-badge--neutral {
    background: var(--app-surface-alt, #eeeef0);
    color: var(--app-muted, #6f6f7d);
}

/*
 * UI-PASS-04B: generic "related person" inline pattern — small avatar +
 * linked name, vertically centered as one unit. Introduced for Wine's
 * Oenologist row (renamed from the owner's Wine-only `.oenologist-image-
 * thumb`, which had no other consumers at the time — confirmed by grep
 * before renaming) but deliberately not Wine-named: Plot/Supervisor/
 * Fieldbook have the same "avatar + link to a person's detail page" need
 * for a supervisor/viticulturist, so this lives in the shared entity
 * system rather than being reinvented per domain.
 */
.entity-person-inline {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;
}

.entity-person-inline__avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    object-fit: cover;
    border: 1.5px solid var(--app-border, #e3e6ef);
    background: #f9fafc;
    flex: none;
}

.entity-person-inline__name {
    color: var(--app-primary, #495057);
    font-weight: 600;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.entity-person-inline__name:hover {
    text-decoration: underline;
}

/*
 * UI-PASS-04C: bulk-select toolbar (Plot's "Select all" + selected count),
 * generalized as `entity-*` since the same select-all/count/export pattern
 * applies to any listing with multi-select — kept purely presentational,
 * the #select_all / label[for="select_all"] / #selected-count ids the
 * existing JS (_scripts.blade.php) reads and writes are untouched, and
 * label[for="select_all"] is left with no nested markup because
 * updateSelectAllLabel() replaces its whole innerText on every toggle.
 */
.entity-bulk-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    padding: .6rem .9rem;
    margin-bottom: 1rem;
    border: 1px solid var(--app-border, #e9e9e9);
    border-radius: 8px;
    background: #f8f9fb;
}

.entity-bulk-toolbar__select {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.entity-bulk-toolbar__checkbox {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--app-primary, #2563a8);
}

.entity-bulk-toolbar__select-label {
    font-weight: 600;
    font-size: .85rem;
    color: #343a40;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
}

/*
 * UI-PASS-05: `.entity-count` is the same "N selected" counter standing on
 * its own, for the listings that show the count without a select-all toolbar
 * (plot certifications, plot audits, yield estimations, invoice orders).
 * They used to be `<span class="badge badge-info">`, a fixed light blue that
 * belongs to no module; the counter now takes the module accent exactly like
 * the toolbar one, so the two share these rules instead of duplicating them.
 * The `#selected-count` id the existing JS writes innerText on is untouched.
 */
.entity-bulk-toolbar__count,
.entity-count {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .82rem;
    color: var(--app-muted, #868e96);
}

.entity-count--end {
    justify-content: flex-end;
}

.entity-bulk-toolbar__count i,
.entity-count i {
    color: var(--app-primary, #2563a8);
}

.entity-bulk-toolbar__count-value,
.entity-count__value {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 .4rem;
    border-radius: 11px;
    background: var(--app-primary, #2563a8);
    color: #fff;
    font-weight: 700;
    font-size: .78rem;
}

/* Per-card selection checkbox + selected-state highlight, shared by all
 * three Plot listing variants (Seller/Supervisor/Fieldbook all use the
 * same .plot_checkbox class already read by the existing bulk-select JS —
 * no class rename, so nothing there needs to change). */
.plot_checkbox {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--app-primary, #2563a8);
    vertical-align: middle;
}

/* ===========================================================================
 * CONTAINER (COMPONENTS-05) — shared Seller/Supervisor Container listing.
 * Extracted from the duplicated inline <style> blocks that used to live in
 * seller/containers/index.blade.php, archived.blade.php and
 * supervisor/containers/list.blade.php (byte-identical across all three).
 * Consumed by resources/views/components/container/*.blade.php. Display
 * only — carries no ownership/permission logic.
 * ======================================================================= */
.container-list-item {
    border: 1px solid #ddd;
    border-radius: 5px;
    padding: 15px;
    margin-bottom: 15px;
    background-color: #fff;
    position: relative;
}

.container-list-item .row > [class*="col-"] {
    margin-bottom: 10px;
}

.container-list-item img {
    width: 70px;
    height: 70px;
    object-fit: cover;
    border-radius: 5px;
}

@media (max-width: 767px) {
    .container-list-item .text-right {
        text-align: left !important;
        margin-top: 10px;
    }
}

.container-room-label {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 4px 8px;
    border-radius: 3px;
    font-size: 12px;
    color: #fff;
    text-transform: uppercase;
}

.container-room-label--clickable {
    cursor: pointer;
}

.container-room-label--unassigned {
    background-color: #808080;
}

.container-content-tag {
    padding: 4px 8px;
    border-radius: 3px;
    font-size: 12px;
    color: #fff;
    text-transform: uppercase;
    cursor: default;
    display: inline-block;
}

.container-content-tag--wine {
    background-color: #800020;
}

.container-content-tag--harvest {
    background-color: #d4af37;
}

.container-content-tag--external_grape {
    background-color: #4b0082;
}

.container-content-tag--lees {
    background-color: #4d6c34;
}

.container-content-tag--pomace {
    background-color: #c67d3c;
}

.container-content-tag--none {
    background-color: #808080;
}

.container-capacity__progress {
    height: 20px;
    margin-bottom: 0;
}

.entity-card:has(.plot_checkbox:checked) {
    border-color: var(--app-primary, #2563a8);
    box-shadow: 0 0 0 2px var(--app-primary-soft, #eaf1fa);
}

/* ==========================================================================
   REQUEST (COMPONENTS-06) — shared visual primitives for the Seller/Supervisor
   Request workflows (SupervisorRequest + SupervisorBottleLabelRequest).
   Colors below intentionally mirror the existing .request-state-bar hex
   values in public/assets/css/custom-style.css — do not diverge from them.
   ========================================================================== */

.request-status-badge.status-pending {
    background-color: #ffe072;
    color: #6b5900;
}

.request-status-badge.status-approved {
    background-color: #85d177;
    color: #ffffff;
}

.request-status-badge.status-rejected {
    background-color: #e76868;
    color: #ffffff;
}

.request-status-badge.status-in_review {
    background-color: #b0a9e7;
    color: #2d2560;
}

.request-status-badge.status-completed {
    background-color: #6ec4e8;
    color: #ffffff;
}

.request-status-badge.status-cancelled {
    background-color: #bbb;
    color: #ffffff;
}

.request-status-badge--label {
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
 * CSS-12 seccion 20: los siete listados de no conformidades
 * (end-of-harvest, harvest_survey, maintenance_cellar_survey,
 * maintenance_plot_survey, mid-harvest, start-of-harvest,
 * vineyard_plot_survey y wine_surveys) llevaban cada uno el mismo mapa de
 * hexadecimales en un @php y lo pintaban con style="background: ...". Es
 * color de ESTADO, no de tema, asi que pasa a ser un vocabulario con nombre
 * y compartido en lugar de ocho copias sueltas.
 *
 * Los valores son exactamente los que ya tenian esas paginas, del mismo
 * repertorio que .request-status-badge de aqui arriba: esta seccion no
 * cambia como se ve ninguna pagina, solo saca el color del marcado.
 */
.nc-status--open {
    background-color: #ffe072;
}

.nc-status--in_review {
    background-color: #6ec4e8;
}

.nc-status--solved_by_seller {
    background-color: #d1ecf1;
}

.nc-status--closed_by_supervisor {
    background-color: #85d177;
}

.nc-status--unknown {
    background-color: #bbb;
}

/* La etiqueta de estado tenia la misma forma repetida en los ocho ficheros. */
.nc-status-label,
.survey-status-label {
    color: #222;
    font-size: 13px;
    font-weight: 700;
    width: fit-content;
    padding: 7px 18px;
    border-radius: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
 * CSS-12 seccion 20: los trece listados de encuestas (end-of-harvest,
 * mid-harvest, start-of-harvest, harvest_survey, wine_surveys,
 * vineyard_plot_survey, maintenance_plot_survey y maintenance_cellar_survey,
 * con sus archivados) repetian por decimocuarta vez el mismo mapa de seis
 * hexadecimales dentro de un @php y lo pintaban con style="background: ...".
 * Es el mismo repertorio que ya usan .request-status-badge y .nc-status--*,
 * asi que aqui no aparece ningun color nuevo: solo deja de estar escrito a
 * mano en cada pagina.
 *
 * La forma la comparten con .nc-status-label de aqui arriba porque era
 * identica declaracion por declaracion. Siete de esas paginas repetian ademas
 * display:flex inline, que .state-badge (custom-style.css) ya les daba.
 *
 * El gris de .survey-status-label es el estado desconocido: antes lo ponia el
 * `?? '#bbb'` del array y ahora lo pone la clase base cuando el modificador
 * no existe. Por eso los modificadores van detras, para ganar por orden.
 *
 * Seller tiene diez ficheros con este mismo patron y se quedan como estan:
 * la seccion 2 dice que Seller es referencia, no ambito.
 */
.survey-status-label {
    background-color: #bbb;
}

.survey-status--pending {
    background-color: #ffe072;
}

.survey-status--approved {
    background-color: #85d177;
}

.survey-status--rejected {
    background-color: #e76868;
}

.survey-status--in_review {
    background-color: #b0a9e7;
}

.survey-status--completed {
    background-color: #6ec4e8;
}

.survey-status--cancelled {
    background-color: #bbb;
}

.request-pdf-viewer__frame {
    border: 1px solid #000;
}

.request-qr-block {
    text-align: center;
}

/*
 * CSS-12/13 seccion 20/21: el enlace que despliega las entradas de una
 * estimacion estaba definido tres veces (supervisor/yield-estimations/index,
 * supervisor/field-activities/harvest y fieldbook/yield-estimations/index) con
 * las mismas tres declaraciones y el mismo azul de Bootstrap escrito a mano.
 * Ese azul no significaba nada: es un enlace, asi que lo pinta el tema. En
 * Fieldbook, ademas, era el azul suelto que la seccion 14 pedia quitar.
 */
.btn-toggle-entries {
    cursor: pointer;
    color: var(--primary, #1d4e89);
    text-decoration: underline;
}

/*
 * Las otras tres reglas del mismo bloque venian de la misma copia: el panel de
 * una cosecha, el subpanel de sus entradas y la tabla que despliega. Estaban
 * escritas igual, declaracion por declaracion, en las mismas tres paginas (en
 * Fieldbook minificadas, pero con los mismos valores), asi que se leen aqui una
 * vez. Los tres grises son neutros de Bootstrap, no color de tema ni de estado:
 * la seccion 20 dice que un neutro se queda como esta, y lo que sobraba no era
 * el gris sino tenerlo tres veces.
 */
.harvest-section {
    background-color: #f8f9fa;
    padding: 15px;
    margin-bottom: 20px;
    border-radius: 8px;
    border: 1px solid #dee2e6;
}

.entries-section {
    background-color: #e9ecef;
    padding: 10px;
    margin-bottom: 5px;
    border-radius: 5px;
}

.entry-table {
    display: block;
    width: 100%;
}

/* =============================================================================
 * SECTION 14 - Stats chart cards (CSS-11)
 *
 * The three Seller "stats" pages (invoice/invoices, orders/customer,
 * orders/wholesale) were the last consumers of the Black Dashboard theme:
 * each one pulled three vendor stylesheets and eight scripts just to lay out a
 * few Chart.js canvases. Black Dashboard is a DARK theme, so those pages have
 * been rendering dark-theme rules inside the light Seller layout ever since —
 * the exact inconsistency this pass exists to close.
 *
 * Everything those vendor stylesheets actually contributed to these pages is
 * below: a muted caption over the card title, and a fixed-height box so the
 * canvas has something to be responsive against. The cards themselves are the
 * ordinary AIZ .card, so they now pick up the Seller theme like every other
 * card in the panel. Colours come from the module tokens; nothing here is
 * theme-specific, so Supervisor and Fieldbook get the same treatment if they
 * ever grow a stats page.
 *
 * Chart.js itself is unaffected: it keeps the exact 2.7.1 build the charts in
 * public/assets/js/stats.js are written against, only served from a neutral
 * path now that the theme it shipped with is gone.
 * ========================================================================== */

.stats-chart {
    overflow: hidden;
}

.stats-chart__category {
    margin-bottom: 5px;
    font-size: 0.75rem;
    font-weight: 400;
    text-transform: capitalize;
    color: var(--app-muted, #6c757d);
}

.stats-chart .card-title {
    margin-bottom: 0;
}

.stats-chart .card-title i {
    margin-right: 5px;
    margin-bottom: 3px;
    font-size: 16px;
}

/* The canvas is responsive inside this box, so the box is what sets the size. */
.stats-chart__area {
    position: relative;
    width: 100%;
    height: 220px;
}

.stats-chart .card-body {
    padding-left: 5px;
    padding-right: 5px;
}

.stats-chart .table {
    margin-bottom: 0;
}

/* =======================================================================
 * SECTION 15 - Referencia SIGPAC: las casillas del codigo de parcela (CSS-12/13)
 * ===================================================================== */
/*
 * Las seis partes del codigo SIGPAC (provincia, municipio, agregado, zona,
 * poligono, parcela) se piden en casillas separadas, cada una con su etiqueta
 * y su descripcion pequena debajo. El mismo bloque de 77 lineas estaba copiado
 * palabra por palabra en los seis formularios de parcela de Seller, Supervisor
 * y Fieldbook.
 *
 * Aqui suben solo las reglas propias del dominio (.sigpac-* y .code-desc), con
 * los mismos valores que ya tenian: no cambia como se ve ningun formulario.
 *
 * Lo que NO sube son los dos ajustes de .alert-secondary y .btn-dark que
 * acompanaban al bloque: esos dos nombres son clases globales de Bootstrap y
 * el ajuste lleva !important, asi que traerlo a esta hoja lo aplicaria a toda
 * la aplicacion en vez de a esa pagina. Se quedan donde estaban.
 *
 * seller/plot/create y seller/plot/edit conservan su copia local (la seccion 2
 * de CSS-12/13 no reabre migraciones de Seller); como los valores son los
 * mismos, la pagina de Seller se ve igual reciba la regla de donde la reciba.
 */
.sigpac-grid {
    gap: 8px;
    flex-wrap: wrap;
}

.sigpac-part-wrap {
    min-width: 90px;
    max-width: 120px;
    margin-bottom: 0.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #f7f7f7;
    border-radius: 7px;
    padding: 7px 3px 3px 3px;
    border: 1px solid #e5e7eb;
}

.sigpac-label {
    font-size: 0.83rem;
    color: #444;
    font-weight: 600;
    margin-bottom: 2px;
    line-height: 1.1;
    text-align: center;
}

/* La aclaracion en gris pequeno bajo cada etiqueta. */
.code-desc {
    font-size: 0.72rem;
    color: #b1b1b1;
    font-weight: 400;
}

/* El guion que separa visualmente una casilla de la siguiente. */
.sigpac-dash {
    font-size: 1.3rem;
    color: #dadada;
    margin: 0 2px;
    user-select: none;
}

/* En pantalla estrecha las casillas se apilan y los guiones sobran. */
@media (max-width: 900px) {
    .sigpac-grid {
        flex-direction: column;
        align-items: flex-start !important;
    }

    .sigpac-part-wrap {
        min-width: 100%;
        max-width: 100%;
        align-items: flex-start;
    }

    .sigpac-dash {
        display: none;
    }
}

/* =======================================================================
 * SECTION 16 - Analisis de vendimia: pestanas por ano (CSS-12/13)
 * ===================================================================== */
/*
 * Las tres paginas de analisis meteorologico de vendimia
 * (supervisor/weather/harvest_analysis_table,
 * fieldbook/weather/harvest_analysis_table y
 * fieldbook/weather/harvest_analysis) repetian el mismo aspecto de pestanas en
 * un <style> propio: dos copias identicas y una tercera con el mismo contenido
 * escrito mas compacto.
 *
 * Aquellas reglas apuntaban directamente a `.nav-tabs`, `.tab-content` y
 * `.card-header`, que son nombres globales de Bootstrap: mientras esas paginas
 * estaban abiertas repintaban cualquier pestana que hubiera en ellas, vinieran
 * de donde vinieran. Aqui van colgadas de `.analysis-tabs`, la clase del
 * contenedor de las pestanas de ano, asi que solo alcanzan a lo que se quiso
 * decorar.
 *
 * Seccion 20: el azul #007bff y el morado #5A4E87 no significaban nada, solo
 * estaban escritos. Son color de tema, asi que pasan al token del modulo: las
 * pestanas de Supervisor salen en su azul institucional y las de Fieldbook en
 * su verde, en lugar del azul suelto que la seccion 14 pide no repetir.
 */
.analysis-tabs .nav-tabs {
    border-bottom: 1px solid #ddd;
}

.analysis-tabs .nav-tabs .nav-link {
    background-color: var(--soft-primary);
    border: 1px solid #ccc;
    border-radius: 4px 4px 0 0;
    color: var(--primary);
    margin-right: 5px;
    padding: 12px 20px;
    transition: background-color 0.3s, color 0.3s;
}

.analysis-tabs .nav-tabs .nav-link.active {
    background-color: var(--primary);
    color: #fff;
    border-color: var(--primary);
    border-bottom-color: transparent;
}

.analysis-tabs .nav-tabs .nav-link:hover {
    background-color: var(--soft-primary);
    color: var(--hov-primary);
}

.analysis-tabs .tab-content {
    border: 1px solid #ddd;
    padding: 20px;
    background-color: #fff;
    border-radius: 0 0 4px 4px;
}

/* Las fichas de dentro se pliegan al pulsar su cabecera. */
.analysis-tabs .card-header {
    cursor: pointer;
}

.analysis-tabs .card-header.bg-light-primary {
    background-color: var(--primary) !important;
    color: #fff !important;
}

/* =======================================================================
 * SECTION 17 - Hoja de encuesta de vendimia: modal por pestanas (CSS-12)
 * ===================================================================== */
/*
 * El modal `#sheetModal` es la hoja de la encuesta: una leyenda arriba y una
 * pestana por bloque de preguntas. Lo usan siete listados de Supervisor
 * (inicio, mitad y fin de vendimia, la encuesta general y sus archivados) pero
 * solo tres llevaban el <style> que lo decora: start-of-harvest/index,
 * harvest_survey/index y harvest_survey/archived. En los otros cuatro el mismo
 * modal salia sin arreglar. Al vivir aqui, la familia entera se ve igual.
 *
 * Los selectores son los mismos que tenian, salvo dos que apuntaban a nombres
 * globales y ahora cuelgan del modal: `.is-invalid` (repintaba cualquier campo
 * invalido de la pagina) y `.nav-tabs .nav-link.tab-complete` (cualquier
 * pestana). Los valores no cambian.
 */

/* Fondo mas suave a la leyenda y separacion extra */
#sheetModalBody > .mb-3,
#sheetModalBody > .mb-2,
#sheetModalBody > div[style*="background:#f9fafd"] {
    background: #f9fafd !important;
    border-radius: 8px;
    border: 1px solid #dde1ee;
    padding: 10px 18px 8px 18px;
    margin-bottom: 16px;
    font-size: 1.07em;
}

/* Tabs mas visibles y scrollables si hay muchas */
#sheetTabs {
    border-bottom: 2px solid #e2e5ec !important;
    box-shadow: 0 3px 8px -6px #aaa;
}

#sheetTabs .nav-link {
    font-weight: 500;
    font-size: 1.07em;
    color: #424d58;
    padding: 8px 22px 9px 22px;
    border-radius: 7px 7px 0 0;
    margin-right: 2px;
    background: #f6f8fb;
    border: 1px solid #dee3ef;
    border-bottom: none !important;
    transition: background 0.2s;
}

#sheetTabs .nav-link.active,
#sheetTabs .nav-link:focus {
    background: #fff !important;
    color: #2364a0 !important;
    border-bottom: 2px solid #fff !important;
    box-shadow: 0 4px 12px -8px #b8c7db;
}

/* La pestana cuyo bloque ya esta contestado del todo. */
#sheetTabs .nav-link.tab-complete {
    color: #16a34a !important;
    font-weight: 600;
}

#sheetTabs .nav-link.tab-complete i {
    vertical-align: -1px;
}

/* Cabecera de cada tab, mas visible */
#sheetTabsContent > .tab-pane > .mb-3 {
    background: #f0f3f9 !important;
    border-radius: 6px;
    border: 1px solid #e5e7f1;
    padding: 12px 22px 10px 22px;
    margin-bottom: 18px;
    font-size: 1.11em;
    font-weight: 600;
    color: #253040;
}

/* Campos formulario: mas separados y limpios */
#sheetTabsContent .form-group {
    margin-bottom: 17px;
}

#sheetTabsContent label {
    font-weight: 500;
    font-size: 1em;
    margin-bottom: 5px;
}

/* Botones: azul y gris claro bien visibles, margen dcho */
#sheetTabsContent .btn-primary {
    min-width: 140px;
    font-weight: 500;
    letter-spacing: .03em;
}

#sheetTabsContent .btn-light,
#sheetTabsContent .btn-secondary {
    background: #f6f6fa;
    color: #4e566d;
    border: 1px solid #cfd7e2;
}

#sheetTabsContent .btn-light:hover,
#sheetTabsContent .btn-secondary:hover {
    background: #e3e9f3;
    color: #222;
}

#sheetTabsContent .d-flex.justify-content-end {
    border-top: 1px solid #e6e7eb;
    padding-top: 12px;
    margin-top: 8px;
    gap: 8px;
}

/* Campo con error dentro de la hoja. */
#sheetModalBody .is-invalid,
#sheetModalBody .form-control.is-invalid {
    border-color: #e2513d;
    background: #fff4f4;
}

/* La tabla ancha de la hoja se arrastra en horizontal: barra bien visible. */
#sheetModalBody .table-responsive {
    scrollbar-width: thick;
    scrollbar-color: #b3b9c9 #e9edf5;
}

#sheetModalBody .table-responsive::-webkit-scrollbar {
    height: 14px;
}

#sheetModalBody .table-responsive::-webkit-scrollbar-thumb {
    background: #b3b9c9;
    border-radius: 7px;
}

#sheetModalBody .table-responsive::-webkit-scrollbar-track {
    background: #e9edf5;
    border-radius: 7px;
}

@media (max-width: 600px) {
    #sheetTabs .nav-link {
        padding-left: 10px;
        padding-right: 10px;
        font-size: 0.99em;
    }

    #sheetTabsContent > .tab-pane > .mb-3 {
        font-size: .98em;
        padding: 8px 7px 6px 9px;
    }

    #sheetModalBody > .mb-3 {
        font-size: .98em;
        padding: 8px 7px 6px 9px;
    }
}

/* =======================================================================
 * SECTION 18 - Ficha de vendimia seleccionable (CSS-12)
 * ===================================================================== */
/*
 * Las dos altas de encuesta de vendimia (start-of-harvest/create y
 * harvest_survey/create) presentan las vendimias como fichas que se pulsan
 * para elegirlas. El bloque estaba repetido identico en las dos.
 *
 * Seccion 20: los azules sueltos (#cbe1fa, #2980ec, #3976ad y la franja
 * degradada) eran color de tema escrito a mano, asi que pasan al token del
 * modulo. La ficha sale ahora en el azul institucional de Supervisor en lugar
 * de en un azul parecido pero distinto.
 */
.harvest-card-b {
    border-radius: 10px;
    border: 1.5px solid var(--soft-primary);
    background: var(--app-surface-alt, #fafdff);
    box-shadow: 0 2px 8px rgba(10, 104, 218, 0.08);
    min-width: 230px;
    padding: 0;
    margin-bottom: 20px;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    transition: box-shadow .2s, border .2s;
}

.harvest-card-b.selected,
.harvest-card-b:hover {
    border-color: var(--primary);
    box-shadow: 0 4px 16px rgba(41, 128, 236, 0.10);
}

.harvest-card-b .header {
    background: var(--primary);
    color: #fff;
    font-weight: 600;
    padding: 0.8rem 1.1rem;
    border-radius: 10px 10px 0 0;
    text-align: center;
}

.harvest-card-b .block {
    padding: 0.5rem 1.2rem;
    border-bottom: 1px solid #f2f2f2;
    display: flex;
    justify-content: space-between;
}

.harvest-card-b .block:last-child {
    border-bottom: none;
}

.harvest-card-b .label {
    color: var(--primary);
    font-weight: 500;
}

.harvest-card-b .value {
    color: #333;
    font-weight: 400;
}
