/*
 * Zahra Nisa admin theme — DESIGN.md section 9, TIER A ONLY.
 *
 * This file restyles Django admin's own markup. Django admin's CSS is not a
 * public API, so every selector here is a bet against a future release, and
 * the bet is kept deliberately small: Django's own custom properties, plus
 * additive rules on selectors that have been stable for well over a decade
 * (#header, #content, .module, #changelist, .results, .form-row,
 * .submit-row, .object-tools, .paginator).
 *
 * What this file must NOT do (Tier B, forbidden): re-lay-out fieldsets with
 * grid, override widget internals, restructure the changelist table, or
 * re-template change_form.html. If a screen genuinely needs a different
 * layout it is not a change form — it is a task screen, and task screens
 * live in backoffice.css where Django cannot break them.
 *
 * tokens.css is loaded before this file, so everything below references
 * var(--cocoa) and friends rather than repeating hexes. That is also what
 * lets tests/test_template_hygiene.py assert there are no raw hex values
 * here.
 */

/* ---- Django's own custom properties -----------------------------------
   Declared on :root and on both explicit theme toggles. Django's
   dark_mode.css loads before this file, so redeclaring wins the cascade for
   :root/prefers-color-scheme — but html[data-theme="dark"] needs its own
   matching selector to win on specificity when a staff member manually
   toggles dark mode. Branding must not revert to Django's defaults because
   of an OS preference. */
:root,
html[data-theme="light"],
html[data-theme="dark"] {
  --primary: var(--cocoa);
  --primary-fg: var(--sand);
  --accent: var(--sand); /* drives #site-name a's colour specifically */
  --header-color: var(--sand);
  --header-bg: var(--cocoa);
  --header-link-color: var(--sand);
  --header-branding-color: var(--sand);
  --link-fg: var(--cocoa);
  --link-hover-color: color-mix(in srgb, var(--cocoa) 80%, black);
  --link-selected-fg: var(--cocoa);
  --button-bg: var(--cocoa);
  --button-hover-bg: color-mix(in srgb, var(--cocoa) 80%, black);
  --default-button-bg: var(--cocoa);
  --default-button-hover-bg: color-mix(in srgb, var(--cocoa) 80%, black);
  /* Oat. The breadcrumb bar sits directly under the Cocoa header and
     Django's default teal clashed visibly there. */
  --breadcrumbs-bg: var(--oat);
  --breadcrumbs-fg: var(--cocoa);
  --breadcrumbs-link-fg: var(--cocoa);

  /* The rest of Django's palette, which the first version of this file left
     alone — and which was why the admin still read as a Django install with
     a brown header on it. Every value below was a hex belonging to Django's
     own scheme: #fff surfaces on a Sand-branded site, #333 body text rather
     than Cocoa, #ccc borders, a yellow #ffc row highlight.

     Setting these rather than chasing selectors is the safest tier there is
     — they are Django's documented theming surface, so this reaches every
     changelist, change form, inline, widget and message without depending on
     any markup staying as it is today. */
  --body-fg: var(--cocoa);
  --body-bg: var(--sand);
  --body-quiet-color: var(--color-text-muted);
  --body-medium-color: var(--color-text-primary);
  --body-loud-color: var(--cocoa);

  --hairline-color: var(--color-border-soft);
  --border-color: var(--color-border-soft);

  /* One step deeper than the page, for striped rows and table headers. */
  --darkened-bg: color-mix(in srgb, var(--oat) 22%, var(--sand));
  --selected-bg: var(--color-surface-soft);
  /* Django's default here is #ffc, a highlighter yellow. */
  --selected-row: var(--color-surface-soft);

  /* Messages. Never colour alone — Django writes the word into each one, so
     the wash only makes it findable. Warning takes neutral Oat rather than a
     second rust, so "needs attention" and "went wrong" stay distinguishable
     without inventing a hue. */
  --message-success-bg: var(--color-positive-soft);
  --message-warning-bg: var(--color-surface-soft);
  --message-error-bg: var(--color-attention-soft);
  --error-fg: var(--color-attention);
  --delete-button-bg: var(--color-attention);
  --delete-button-hover-bg: color-mix(in srgb, var(--color-attention) 82%, black);

  --object-tools-bg: var(--cocoa);
  --object-tools-hover-bg: color-mix(in srgb, var(--cocoa) 80%, black);

  /* Jost through Django's own variable rather than a selector list of ours.
     This is what reaches the widgets, the filter sidebar and the paginator. */
  --font-family-primary: var(--font-body);
}

/* ---- Typography --------------------------------------------------------
   The typeface itself comes from --font-family-primary above rather than a
   selector list here. That was tried first — `body, input, select, textarea,
   button, .button { font-family: ... }` — and removing it changed nothing
   measurable on four different admin pages, because Django's own variable
   already reaches everything including the widgets and the filter sidebar.
   Only the things Django has no variable for are set below. */

/* The header wordmark gets the brand's real treatment — light weight, wide
   tracking, caps — matching the shop front's. */
#site-name a {
  font-family: var(--font-display);
  font-weight: var(--font-weight-light);
  font-size: var(--text-lg);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
}

/* Section headings and column headers as small caps, which is what makes a
   dense screen scannable without needing bold weight. Jost has only two
   weights here and neither is a heading weight. */
.module caption,
#changelist .results thead th,
.inline-group h2,
fieldset.module h2 {
  font-family: var(--font-display);
  font-weight: var(--font-weight-regular);
  font-size: var(--text-xs);
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
}

/* ---- Density and alignment --------------------------------------------
   "Nothing is aligned" was the complaint. Most of it is this: Django's
   default row padding is generous and its numeric columns are
   left-aligned in a proportional font, so a column of prices never lines
   up on its decimal point. */
#changelist .results td,
#changelist .results th {
  padding-block: var(--space-1);
  padding-inline: var(--space-1);
  vertical-align: middle;
}

/* Every figure in the admin is money or a count. Tabular numerals make the
   digits equal-width so a column reads as a column; end-alignment is what
   actually lines up the last digit, and does the job even if Jost turns out
   not to carry a tnum feature. */
#changelist .results td.field-total_display,
#changelist .results td.field-price_display,
#changelist .results td.field-quantity_on_hand,
#changelist .results td.field-quantity_reserved,
#changelist .results td.field-available_display,
#changelist .results td.field-reorder_point,
#changelist .results td.field-delta {
  font-variant-numeric: tabular-nums;
  text-align: end;
  /* An amount is one thing and must not break across lines. Without this
     the total column wrapped as "PKR" above "8,700.00", which defeats the
     alignment the rest of this rule exists for. */
  white-space: nowrap;
}

/* Row separators as hairlines rather than full-strength borders — the same
   reasoning as --color-border-soft on the shop front. At this row density a
   full-weight rule between every line turns a table into a grid. */
#changelist .results tbody td,
#changelist .results tbody th {
  border-block-end: 1px solid var(--color-border-soft);
}

/* ---- Surfaces ----------------------------------------------------------
   Modules pick up the brand's radius so panels stop reading as squares in a
   rounded interface. --radius-sm, not --radius-lg: DESIGN.md's three radius
   tiers are chosen by affordance, and a module is content, not a band. */
.module,
.inline-group,
#changelist-form,
.object-tools a {
  border-radius: var(--radius-sm);
}

/* The model list and the Recent actions panel, made to match the dashboard
   sitting directly above them.

   Measured before changing: the modules were pure white against a Sand page,
   their body text was Django's #333 rather than Cocoa, and each group
   heading was a solid Cocoa bar with square corners inside an 8px-rounded
   box. Individually small; together they are why the lower half of the home
   page still read as a different application from the top half.

   The heading loses its dark fill deliberately. Six solid Cocoa bars down
   one page is far past the 10% the brand's 60/30/10 ratio allows, and the
   dashboard's own band titles are quiet small caps — so this is the app list
   adopting the dashboard's language rather than the reverse. */
#content-main .module,
#content-related .module {
  background: var(--color-surface-soft);
  color: var(--color-text-primary);
  overflow: hidden;
}

#content-main .module caption,
#content-related .module h2,
#content-related .module caption {
  background: none;
  color: var(--color-text-primary);
  font-family: var(--font-display);
  font-weight: var(--font-weight-regular);
  font-size: var(--text-xs);
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
  padding-block: var(--space-2) var(--space-1);
  padding-inline: var(--space-2);
}

#content-main .module caption a.section,
#content-related .module caption a.section {
  color: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
}

/* Hairlines, not full-strength borders — the same reasoning as the
   changelist rows and the dashboard's own tables. */
#content-main .module tbody th,
#content-main .module tbody td {
  background: none;
  border-block-end: 1px solid var(--color-border-soft);
  padding-block: var(--space-1);
}

#content-main .module tbody tr:last-child th,
#content-main .module tbody tr:last-child td {
  border-block-end: none;
}

#content-main .module tbody th a,
#content-main .module tbody td a {
  color: var(--color-text-primary);
}

/* The Add / Change / View icons, recoloured.

   Django ships them as SVGs with the fill baked in — #5fa225 green,
   #b48c08 gold, #2b70bf blue. Three colours in no token file, on the
   brand's own home page, and the last obviously-not-ours thing on it.

   They cannot be edited (they belong to the installed package) and a
   background-image cannot inherit currentColor, so Django's own file is
   used as a *mask* and the colour comes from the text. That also means the
   icons follow the link colour automatically, including on hover and in
   dark mode, which a re-coloured copy would not. */
#content-main .addlink,
#content-main .changelink,
#content-main .viewlink,
#content-main .inlinechangelink,
#content-main .inlineviewlink {
  background-image: none;
  position: relative;
}

#content-main .addlink::before,
#content-main .changelink::before,
#content-main .viewlink::before,
#content-main .inlinechangelink::before,
#content-main .inlineviewlink::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.2em;
  inline-size: 13px;
  block-size: 13px;
  background-color: currentColor;
  -webkit-mask: var(--zn-icon) center / contain no-repeat;
  mask: var(--zn-icon) center / contain no-repeat;
}

#content-main .addlink::before {
  --zn-icon: url("../admin/img/icon-addlink.svg");
}

#content-main .changelink::before,
#content-main .inlinechangelink::before {
  --zn-icon: url("../admin/img/icon-changelink.svg");
}

#content-main .viewlink::before,
#content-main .inlineviewlink::before {
  --zn-icon: url("../admin/img/icon-viewlink.svg");
}

/* Recent actions: the same wash, and the list inherits the panel rather
   than sitting on white. */
#content-related .module ul.actionlist li {
  border-block-end: 1px solid var(--color-border-soft);
  padding-block: var(--space-1);
}

#content-related .module ul.actionlist li:last-child {
  border-block-end: none;
}

/* Actionable controls take the pill, matching the shop front's rule that
   every "press me" control is fully rounded. */
.object-tools a,
.submit-row input,
.submit-row a.deletelink,
.button {
  border-radius: var(--radius-pill);
}

.submit-row {
  border-radius: var(--radius-sm);
  gap: var(--space-1);
}

/* Form fields match the storefront's input treatment — --radius-sm, because
   a text box is data entry, not an action. */
.form-row input[type="text"],
.form-row input[type="email"],
.form-row input[type="url"],
.form-row input[type="tel"],
.form-row input[type="number"],
.form-row input[type="password"],
.form-row textarea,
.form-row select {
  border-radius: var(--radius-sm);
}

/* ---- The index page's width -------------------------------------------
   Django's base.css carries `.dashboard #content { width: 600px }` — a
   hardcoded column sized for what the index used to be, a list of app links
   and nothing else. With the dashboard on it, that left the bands in a
   600px strip beside roughly 750px of empty page at 1440.

   Overridden only on the index (`body.dashboard`, 1-0-1-1, one step above
   Django's 1-0-1-0) and only the width. `.colMS` still reserves its 300px
   for the Recent actions sidebar, so nothing else about the layout moves. */
body.dashboard #content {
  width: auto;
}

/* ---- Focus -------------------------------------------------------------
   One ring, the same one the shop front uses, on everything focusable.
   Django's default varies by element. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.button:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}
