/*
 * The admin's OpenCart-shaped skin, in this project's black and white.
 *
 * Loaded through UNFOLD["STYLES"], which injects it after the theme's own
 * stylesheet on every admin page. That is the whole reason this is a stylesheet
 * and not a fork of django-unfold's CSS build: the theme stays a dependency you
 * can upgrade, and everything below is one file to re-check when you do.
 *
 * The rule this file follows, learned the hard way twice: only draw what the
 * theme does not already draw. Unfold puts a bottom border on every field row,
 * a box around the search area, and — the one that is easy to miss — a bordered
 * *wrapper* around inputs rather than a border on the input itself, which is
 * how the search box gets its icon and a price its "$". Bordering the input as
 * well therefore draws a second box inside the first.
 *
 * Adding a border here is not a neutral act. Look at the rendered markup for
 * the element first, and at its parent.
 *
 * Specificity: the theme styles with Tailwind utility classes, which are
 * single-class selectors. Rules here lead with an id (#content-main,
 * #result_list) so they win on specificity rather than on !important. Where a
 * utility genuinely cannot be outranked that way it is marked, and only there.
 */

:root {
    --oc-line: #dddddd;
    --oc-line-strong: #cccccc;
    --oc-head: #f9f9f9;
    --oc-hover: #f5f5f5;
    --oc-radius: 3px;

    /* The theme's own corner, read by every `rounded-default` element it
       renders — panels, buttons, inputs, the lot. Setting it here rather than
       restyling those elements one by one is the whole reason a single line
       squares off the entire admin. 6px is the theme's default and reads soft
       for a tool; 3px keeps the edge without going hard-cornered. */
    --border-radius: 3px;

    /* Tailwind's named steps, used by the handful of places that ask for a
       size rather than the default. Brought down in proportion so nothing
       ends up rounder than the panel containing it. */
    --radius-md: 3px;
    --radius-lg: 4px;
    --radius-xl: 5px;
}

html.dark {
    --oc-line: #374151;
    --oc-line-strong: #4b5563;
    --oc-head: rgba(255, 255, 255, 0.04);
    --oc-hover: rgba(255, 255, 255, 0.06);
}

/* ---- tables ------------------------------------------------------------ */
/* Ruled cells and a header band — the one place the theme genuinely draws less
   than a commerce admin needs. It separates rows with a single hairline and has
   no vertical rules at all, which is legible on four columns and hard work on
   nine. */

#result_list {
    border-collapse: collapse !important;   /* theme sets border-separate */
    border-spacing: 0 !important;
}

#result_list thead th {
    background: var(--oc-head);
    border: 1px solid var(--oc-line);
    font-weight: 600;
    padding: 0.625rem 0.75rem;
    vertical-align: middle;
}

#result_list tbody td,
#result_list tbody th {
    border: 1px solid var(--oc-line);
    padding: 0.625rem 0.75rem;
    vertical-align: middle;
}

/* Outer edges belong to the wrapper the theme draws around the table — the one
   with `lg:border lg:rounded-b-default`, which is the list's actual frame. The
   cells draw the grid inside it and nothing more.
 *
 * This was briefly reversed when the search panel's frame came off, on the
   assumption that the panel had been the only frame. It was not: the table has
   its own wrapper, so letting the cells draw an outer edge as well put two
   lines a pixel apart round the whole list. border-collapse cannot merge those
   — they belong to different elements. */

#result_list thead th {
    border-top: 0;
}

#result_list thead th:first-child,
#result_list tbody tr > *:first-child {
    border-left: 0;
}

#result_list thead th:last-child,
#result_list tbody tr > *:last-child {
    border-right: 0;
}

#result_list tbody tr:last-child > td,
#result_list tbody tr:last-child > th {
    border-bottom: 0;
}

/* The row under the cursor. OpenCart's clearest affordance, and the theme has
   none — on a long list there is nothing tying a name to the price beside it. */
#result_list tbody tr:hover > td,
#result_list tbody tr:hover > th {
    background: var(--oc-hover);
}

/* ---- the save bar ------------------------------------------------------ */
/* OpenCart pins save to the top right of the page. The theme puts the save row
   at the foot of the form, which on a tabbed form means scrolling past whichever
   tab you are on to reach it. Made sticky rather than moved: moving it would
   fight the theme's layout on every screen. The border is the only thing
   separating it from the content scrolling under it, so it stays. */

.submit-row {
    background: #fff;
    border-top: 1px solid var(--oc-line);
    bottom: 0;
    position: sticky;
    z-index: 20;
}

html.dark .submit-row {
    background: #111827;
}

/* ---- movement ---------------------------------------------------------- */
/* Everything that changes appearance on hover or click does so over a beat
   rather than between frames. An instant change reads as a glitch: nothing ties
   the thing you did to the thing that changed. These are short on purpose —
   long enough to be seen as a movement, short enough that nobody waits for it.
 *
 * The theme already eases its own controls; these are the surfaces it leaves
 * to the browser, which by default has no easing at all. */

#result_list tbody tr > td,
#result_list tbody tr > th {
    transition: background-color 120ms ease-out;
}

/* Row controls and anything else with a border that answers the cursor. */
#result_list a,
#content-main .rounded-default {
    transition: background-color 120ms ease-out,
                border-color 120ms ease-out,
                color 120ms ease-out;
}

/* Panels that appear when a tab is chosen. The strip itself already eases its
   underline; without this the panel under it swaps between frames and the two
   halves of one gesture look unrelated. */
.tab-wrapper {
    animation: oc-tab-in 140ms ease-out;
}

@keyframes oc-tab-in {
    from { opacity: 0; transform: translateY(2px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Respect a reader who has asked the system for less movement. Not optional:
   for some people this is a vestibular symptom, not a preference. */
@media (prefers-reduced-motion: reduce) {
    #result_list tbody tr > td,
    #result_list tbody tr > th,
    #result_list a,
    #content-main .rounded-default,
    /* The sidebar fold, which is a grid-row transition — see
       templates/unfold/helpers/app_list.html. */
    #nav-sidebar-apps .grid {
        transition: none;
    }

    .tab-wrapper {
        animation: none;
    }
}

/* ---- the sidebar edge -------------------------------------------------- */
/* The sidebar is told apart from the page by being a different surface, not by
   a rule down its side. A border is a third thing on screen doing the job the
   two backgrounds already do between them — and once the separators inside the
   nav are gone, the one down the edge is the only line left, which makes it
   look like an accident rather than a choice.
 *
 * The tint is deepened a little at the same time: with no border, the panel has
 * to hold its own edge, and the theme's default sits too close to the white of
 * the content beside it to read as a separate surface on a bright screen. */

#nav-sidebar {
    background: #fafafa;
    border-right: 0;
}

html.dark #nav-sidebar {
    background: #0f1115;
    border-right: 0;
}

#nav-sidebar-inner {
    background: transparent;
}

/* No rule under the wordmark. It was the last line left in a sidebar whose
   section separators have all gone, and a single divider with nothing to
   match it reads as something forgotten rather than as structure. The logo is
   set apart by its own space instead. */
#nav-sidebar-inner > div:first-child {
    border-bottom: 0;
    margin-bottom: 0.75rem;
}

/* ---- where you are in the sidebar -------------------------------------- */
/* Three states, because there are three questions: which section is open, what
   is in it, and which of those am I looking at. The theme answers only the last
   one, so an open section looked the same as a closed one with rows under it.
 *
 * All three are carried by surface, not by hue. This admin has no accent colour
 * to spend — the palette is greys — so depth does the work a blue would do in
 * OpenCart, and it keeps working in dark mode where a tint would not.
 *
 * The shape follows OpenCart's: full-width bands, square edges, rows tight
 * enough that a whole section is readable without scrolling. The theme's own
 * spacing is built for a shorter menu than this one.
 *
 * `.nav-section-open` is set by Alpine on the heading; CSS cannot read the
 * variable itself. See templates/unfold/helpers/app_list.html. */

/* Section headings: full width, no inset, no rounding. */
#nav-sidebar-apps h2 {
    border-radius: 0;
    margin: 0;
    padding: 0.5rem 1rem;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}

/* Two colours in the sidebar, and only two.
 *
 * The open section is one of them: the heading and the rows under it share a
 * single surface, because an open section is one thing and shading its lid
 * differently from its contents only made the strip look busy.
 *
 * The row you are on is the other. It is the one place a second colour earns
 * its keep, so it gets a real step away from the section around it — far
 * enough to find without scanning, and nowhere near the white of the content
 * area, which is what made an earlier version read as a hole in the sidebar. */
#nav-sidebar-apps h2.nav-section-open {
    background: #eeeef2;
    color: var(--color-font-important-light, #18181b);
}

html.dark #nav-sidebar-apps h2.nav-section-open {
    background: #191d24;
}

/* The rows inside an open section, as one band.
 *
 * padding: 0 is not cosmetic. The fold works by taking the grid row to 0fr,
 * which zeroes the list's *content* height — padding is not part of that, so
 * any vertical padding here survives the collapse and leaves a grey stripe
 * under every closed section. */
#nav-sidebar-apps .nav-section-items {
    background: #eeeef2;   /* the same surface as the heading above it */
    border-radius: 0;
    margin: 0;
    padding: 0;
}

html.dark #nav-sidebar-apps .nav-section-items {
    background: #191d24;
}

/* Rows: tighter than the theme's 38px, square, full width. */
#nav-sidebar-apps ol {
    gap: 0;
    padding-left: 0;
    padding-right: 0;
}

#nav-sidebar-apps ol a {
    border-radius: 0;
    height: 34px;
    margin: 0;
    padding-left: 2rem;
    padding-right: 1rem;
}

/* The row you are actually on. Strengthened over the theme's, which is a tint
   so light it disappears once the group behind it has one of its own. */
/* The second colour: the row you are on. */
#nav-sidebar-apps ol a.active {
    background: #d9d9e0;
    color: var(--color-font-important-light, #18181b);
    font-weight: 600;
}

#nav-sidebar-apps ol a.active .material-symbols-outlined {
    color: var(--color-font-important-light, #18181b);
}

html.dark #nav-sidebar-apps ol a.active {
    background: #2b313b;
    color: #f4f4f5;
}

html.dark #nav-sidebar-apps ol a.active .material-symbols-outlined {
    color: #f4f4f5;
}

/* Top-level rows that belong to no section — Dashboard, All applications —
   line up with the headings rather than with the indented rows. */
#nav-sidebar-apps > div > ol:not(.nav-section-items) a {
    padding-left: 1rem;
}

/* Sections stack directly on one another. The theme spaces them apart, which
   suits a menu of three groups and leaves this one looking like a list of
   unrelated cards. */
#nav-sidebar-apps > div {
    margin-bottom: 0;
}



/* ---- card headers ------------------------------------------------------ */
/* A titled card gets a header band, the way a panel does in OpenCart. The
   theme gives the title a bottom border and nothing else, so on a white card
   the heading and the content it heads sit on the same surface and the border
   is doing all the work.
 *
 * `.oc-card-title` is passed as `title_class` at each call site rather than
   guessed at with a structural selector — the component supports it, and a
   selector like "the card's first div" breaks the moment the markup moves. */

.oc-card-title {
    background: var(--oc-head);
}

html.dark .oc-card-title {
    background: rgba(255, 255, 255, 0.03);
}

/* ---- the fold, timed --------------------------------------------------- */
/* Kept here rather than in Tailwind classes on the element so the whole
   movement is one place to tune.
 *
 * 320ms and a symmetrical curve. The first attempt used 200ms with ease-out,
 * which is the curve for something arriving — applied to a close it means the
 * section races away and stops dead. ease-in-out reads as the same gesture in
 * both directions, and at this height 200ms is under the threshold where the
 * eye follows the movement rather than just noticing the result. */

#nav-sidebar-apps .nav-section-fold {
    transition: grid-template-rows 320ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* The rows fade slightly behind the slide. Without it the text is legible at
   full strength while the section is still a few pixels tall, which reads as
   the list being cropped rather than opening. Faster on the way in than the
   slide, slower on the way out, so the rows are gone before the gap closes. */
#nav-sidebar-apps .nav-section-fold .nav-section-items {
    opacity: 0;
    transition: opacity 160ms ease-in;
}

#nav-sidebar-apps .nav-section-fold.is-open .nav-section-items,
#nav-sidebar-apps .nav-section-fold[data-open-on-load] .nav-section-items {
    opacity: 1;
    transition: opacity 240ms ease-out 60ms;
}

@media (prefers-reduced-motion: reduce) {
    #nav-sidebar-apps .nav-section-fold,
    #nav-sidebar-apps .nav-section-fold .nav-section-items {
        transition: none;
    }
}

/* ---- the search bar stands alone --------------------------------------- */
/* The theme wraps the search box and the Filters button in a bordered panel,
   then pulls the table up into it with a negative margin so the two read as one
   unit. That is a second frame around a table that already has one, and on a
   page whose only content is a list it is a box around a box.
 *
 * The panel's border and its tuck are removed, so the search sits free above
 * the list and the list is the only bordered thing on the page. The tuck is the
 * part that matters: leaving `-mb-8` behind without the border would pull the
 * table up under nothing and clip its top edge.
 *
 * Selected by the padding utility that is unique to this element, since the
 * theme gives it no id or name of its own. */

#changelist [class*="pb-11"] {
    border: 0 !important;      /* theme sets lg:border */
    margin-bottom: 1rem !important;   /* theme sets lg:-mb-8 */
    padding: 0 !important;     /* theme sets lg:p-3 lg:pb-11 */
}

/* ---- the change form's tab strip --------------------------------------- */
/* Real CSS, not utility classes: the theme's Tailwind is built ahead of time
   from its own source, so any class this project invents — `[&>.active]:...`
   and the like — is absent from the stylesheet and silently does nothing. That
   is exactly how the active tab ended up with no indicator at all.
 *
 * See templates/admin/form_tabs.html, which draws the strip. */

#tabs-items > a {
    border-bottom: 2px solid transparent;
    color: var(--color-font-subtle-light, #71717a);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: -1px;
    padding: 0.625rem 0.875rem;
    transition: border-color 120ms ease-out, color 120ms ease-out;
    white-space: nowrap;
}

#tabs-items > a:hover {
    border-bottom-color: #c4c4c8;
    color: var(--color-font-important-light, #18181b);
}

#tabs-items > a.active {
    border-bottom-color: #18181b;
    color: #18181b;
    font-weight: 600;
}

html.dark #tabs-items > a {
    color: var(--color-font-subtle-dark, #a1a1aa);
}

html.dark #tabs-items > a:hover {
    border-bottom-color: #4b5563;
    color: #f4f4f5;
}

html.dark #tabs-items > a.active {
    border-bottom-color: #f4f4f5;
    color: #f4f4f5;
}

/* ---- the filter drawer ------------------------------------------------- */
/* The classes Alpine swaps on and off the drawer and its scrim. Alpine only
   adds the names; the stylesheet has to define them, and Tailwind's own cannot
   be borrowed — the theme's CSS is built from the theme's source, so a utility
   it never used does not exist. See the template.
 *
 * Out is quicker than in: by the time you are closing it you know what you
   asked for, and waiting to get back to the list is the annoying half. */

.oc-drawer-in {
    transition: opacity 200ms ease-out, transform 200ms ease-out;
}

.oc-drawer-out {
    transition: opacity 140ms ease-in, transform 140ms ease-in;
}

.oc-faded {
    opacity: 0;
}

.oc-offscreen {
    opacity: 0;
    transform: translateX(1.5rem);
}

/* The panel's own arrival. A keyframe, not a transition: it is drawn with its
   wrapper rather than toggled, so there is no "before" state to move from. */
.oc-drawer-panel {
    animation: oc-drawer-slide 220ms cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes oc-drawer-slide {
    from { opacity: 0; transform: translateX(1.5rem); }
    to   { opacity: 1; transform: translateX(0); }
}

.oc-shown {
    opacity: 1;
    transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
    .oc-drawer-in,
    .oc-drawer-out {
        transition: none;
    }

    .oc-offscreen {
        transform: none;
    }

    .oc-drawer-panel {
        animation: none;
    }
}
