/* =====================================================================
   Zam ERP — Windows 95 theme.

   The client asked for the whole ERP to look like the Cost Estimation
   module. This does it WITHOUT touching the 95 page templates, because
   every one of them is already built from the same component classes
   (.btn, .input, .table, .card, .tag, .zg-sidelink). Override those and
   the variables behind them, and every screen changes at once.

   Loaded AFTER industry-plum.css, so these rules win on equal
   specificity. Nothing here raises specificity for its own sake — where
   a selector looks heavier than it needs to be, it is matching the
   weight of the rule it replaces.

   The palette is the real one: Win95 used #c0c0c0 for surfaces, #000080
   for the active title bar, and a 2px outset/inset border to fake light
   coming from the top-left. Rounded corners, shadows and tonal ramps all
   go to zero — they are exactly what makes a modern UI look modern.
   ===================================================================== */

:root {
  /* ---------------------------------------------------------------
     Taken verbatim from cost_estimation/static/cost_estimation/retro.css,
     which the client approved and which is itself the SAP NetWeaver
     Business Client palette from the screenshot he sent on 2026-08-21.

     Copied rather than imported on purpose: cost_estimation is a
     deliberately standalone module (tests_module_boundary enforces it),
     so the ERP must not depend on its static files. If these two ever
     disagree, that file is the original and this one is wrong.

     The first version of this theme used classic Windows 95 grey on a
     teal desktop. That was a guess at what "like Cost Estimation" meant,
     and it was wrong: the real thing is paler, bluer, and white where
     the work happens.
     --------------------------------------------------------------- */
  --r95-face:        #d3dfee;   /* pale blue control face                */
  --r95-panel:       #ffffff;   /* the white working area                */
  --r95-legend:      #dbe7f4;   /* group and column header strip         */
  --r95-field:       #ffffff;   /* editable field interior               */
  --r95-readout:     #eaf3fc;   /* a cell holding a computed figure      */
  --r95-light:       #ffffff;   /* bevel highlight, top and left         */
  --r95-shadow:      #93aac6;   /* bevel shadow, bottom and right        */
  --r95-dark:        #5f7d9e;   /* deeper edge of a doubled bevel        */
  --r95-ink:         #16324f;   /* navy text, not black — SAP never is   */
  --r95-title:       #2f6fad;
  --r95-title-lit:   #4a8bc7;
  --r95-title-text:  #ffffff;
  --r95-action:      #f6e8a0;   /* SAP's yellow for the button that acts */
  --r95-action-edge: #c4ad55;
  --r95-hover:       #eef4fb;
  --r95-muted:       #4a6480;
  --r95-select:      #2f6fad;
  --r95-select-text: #ffffff;

  /* --- what the existing components read ------------------------- */
  --color-bg: var(--r95-panel);        /* white, per the client */
  --color-surface: var(--r95-face);
  --color-text: var(--r95-ink);
  --color-divider: var(--r95-shadow);

  --color-accent: var(--r95-title);
  --color-accent-2: var(--r95-title-lit);
  --color-accent-100: #eef4fb;
  --color-accent-200: #dbe7f4;
  --color-accent-300: #c3d6ea;
  --color-accent-400: #93aac6;
  --color-accent-500: #4a8bc7;
  --color-accent-600: #2f6fad;
  --color-accent-700: #2f6fad;
  --color-accent-800: #1f4f7d;
  --color-accent-900: #16324f;
  --color-accent-2-100: #eef4fb;
  --color-accent-2-200: #dbe7f4;
  --color-accent-2-300: #c3d6ea;
  --color-accent-2-400: #93aac6;
  --color-accent-2-500: #4a8bc7;
  --color-accent-2-600: #2f6fad;
  --color-accent-2-700: #2f6fad;
  --color-accent-2-800: #1f4f7d;
  --color-accent-2-900: #16324f;
  --color-neutral-100: #eef4fb;
  --color-neutral-200: #dbe7f4;
  --color-neutral-300: #c3d6ea;
  --color-neutral-400: #93aac6;
  --color-neutral-500: #7e93ad;
  --color-neutral-600: #5f7d9e;
  --color-neutral-700: #4a6480;
  --color-neutral-800: #2b4766;
  --color-neutral-900: #16324f;

  --font-heading: Tahoma, "MS Sans Serif", Geneva, Verdana, sans-serif;
  --font-heading-weight: 700;
  --font-body: Tahoma, "MS Sans Serif", Geneva, Verdana, sans-serif;

  --radius-md: 0;
  --radius-sm: 0;
  --radius-lg: 0;
}

/* The bevels, as the two things Win95 actually drew: a raised face and a
   sunken well. Everything below is one or the other. */
.r95-out,
.btn, .card, .zg-kpi, .seg-opt, .tag {
  border-style: solid;
  border-width: 2px;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
}

.r95-in,
.input, .table, .zg-palette-dialog {
  border-style: solid;
  border-width: 2px;
  border-color: var(--r95-shadow) var(--r95-light) var(--r95-light) var(--r95-shadow);
}

body {
  background: var(--r95-panel);
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--color-text);
}

a { color: var(--r95-title); }
a:hover { color: var(--r95-title-lit); }

/* --- buttons ------------------------------------------------------ */
.btn {
  background: var(--r95-face);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 12px;
  border-radius: 0;
  padding: 4px 14px;
  min-height: 25px;
  box-shadow: none;
}
.btn:active,
.btn-primary:active,
.btn-secondary:active {
  border-color: var(--r95-dark) var(--r95-light) var(--r95-light) var(--r95-dark);
  /* The press is the whole charm of these buttons: the bevel inverts and
     the label shifts one pixel down-right, as though it were physical. */
  padding: 5px 13px 3px 15px;
}
.btn-primary {
  background: var(--r95-face);
  color: var(--color-text);
  font-weight: 700;
}
.btn-primary:hover { background: #fdf3c4; }
.btn-secondary { background: var(--r95-face); }
.btn-secondary:hover { background: var(--r95-hover); }
.btn-ghost {
  border-color: transparent;
  background: transparent;
  color: #0000c0;
  text-decoration: underline;
}
.btn-ghost:hover { background: transparent; color: #0000ff; }
.btn-icon { width: 24px; height: 24px; min-height: 24px; padding: 0; }
.btn:focus-visible { outline: 1px dotted var(--r95-dark); outline-offset: -5px; }

/* --- fields -------------------------------------------------------- */
.field > label {
  color: var(--color-text);
  font-size: 12px;
  margin-bottom: 3px;
}
.input {
  background: var(--r95-field);
  color: var(--color-text);
  border-radius: 0;
  min-height: 22px;
  padding: 3px 5px;
  font-family: var(--font-body);
  font-size: 12px;
}
.input:hover { border-color: var(--r95-shadow) var(--r95-light) var(--r95-light) var(--r95-shadow); }
.input:focus-visible { outline: none; border-color: var(--r95-shadow) var(--r95-light) var(--r95-light) var(--r95-shadow); }
.input:disabled, .input[readonly] { background: var(--r95-face); color: var(--r95-shadow); }
select.input { padding: 2px 4px; }
textarea.input { min-height: 70px; }

/* --- tables -------------------------------------------------------- */
.table {
  background: var(--r95-panel);
  font-size: 12px;
  border-collapse: separate;
  border-spacing: 0;
}
.table th {
  background: var(--r95-legend);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0;
  text-transform: none;
  padding: 3px 7px;
  border: 2px solid;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
}
.table td {
  padding: 3px 7px;
  border-bottom: 1px solid var(--r95-legend);
  color: var(--color-text);
}
.table tbody tr:hover td { background: var(--r95-hover); }

/* --- cards, dialogs, panels ------------------------------------------ */
.card {
  background: var(--r95-face);
  border-radius: 0;
  gap: 6px;
  padding: 10px;
}
.hr { border: none; border-top: 1px solid var(--r95-shadow); border-bottom: 1px solid var(--r95-light); }

.dialog, .zg-palette-dialog {
  background: var(--r95-face);
  border-radius: 0;
  box-shadow: 2px 2px 0 rgba(0, 0, 0, .5);
}
.dialog-title {
  background: linear-gradient(180deg, var(--r95-title-lit) 0%, var(--r95-title) 100%);
  color: var(--r95-title-text);
  font-weight: 700;
  padding: 3px 6px;
}

/* --- tags ------------------------------------------------------------- */
.tag {
  border-radius: 0;
  font-size: 11px;
  padding: 1px 6px;
  background: var(--r95-face);
  color: var(--color-text);
  border-width: 1px;
  border-color: var(--r95-light) var(--r95-shadow) var(--r95-shadow) var(--r95-light);
}
.tag-success { background: #dceadc; }
.tag-warning { background: var(--r95-note); }
.tag-danger  { background: var(--r95-note-bad, #fbe3e3); }
.tag-neutral { background: var(--r95-face); }
.tag-outline { background: transparent; }

/* --- the shell -------------------------------------------------------- */
/* The sidebar becomes the raised panel a Win95 app would have used, and
   the content area becomes the sunken client area inside it. */
.zg-sidebar, [data-sidebar], aside {
  background: var(--r95-face) !important;
}
.zg-sidelink {
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 12px;
  border-radius: 0;
  padding: 3px 8px;
}
.zg-sidelink:hover { background: var(--r95-hover); }
.zg-sidelink[aria-current="page"] {
  background: var(--r95-select);
  color: var(--r95-select-text);
}
.zg-sidelink[aria-current="page"] .zg-dot { background: var(--r95-select-text); }
.zg-dot { border-radius: 0; background: var(--r95-shadow); }
.zg-chevron { color: var(--color-text); }

.zg-brand, .nav-brand {
  font-family: var(--font-body);
  font-weight: 700;
  color: var(--color-text);
}

/* --- messages ---------------------------------------------------------- */
.zg-message {
  border-radius: 0;
  border: 2px solid;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
  background: var(--r95-face);
  font-size: 12px;
}

/* --- headings ----------------------------------------------------------- */
/* 34px page titles belong to the modern design. A Win95 app put the screen
   name in the title bar and got on with it, so headings come right down.
   Selected through [data-density] to match the specificity of the compact
   rule in industry-plum.css, which carries !important of its own — a plain
   `h1 {}` loses to it however important it declares itself. */
[data-density] h1 { font-size: 18px !important; font-weight: 700; letter-spacing: 0; }
[data-density] h2 { font-size: 15px !important; font-weight: 700; letter-spacing: 0; }
[data-density] h3,
[data-density] h4 { font-size: 13px !important; font-weight: 700; letter-spacing: 0; }

/* --- the client area ------------------------------------------------------ */
/* Content used to sit straight on the desktop teal, which no application
   ever did — the teal is the desktop BEHIND the program, not the page. This
   is the window the program draws itself into. */
.r95-client {
  background: var(--r95-panel);
  border: 2px solid;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
  margin: 6px 6px 6px 0;
  min-height: calc(100vh - 12px);
}

/* --- a window frame for forms and detail pages --------------------------- */
/* Lists and reports stay full-page: a paginated table with filters inside a
   draggable box is worse than the page it replaced. Forms and detail screens
   get the frame, which is where the metaphor actually helps. */
.r95-page-window {
  background: var(--r95-face);
  border: 2px solid;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, .35);
  margin: 14px;
}
.r95-page-titlebar {
  display: flex; align-items: center; gap: 6px;
  background: linear-gradient(180deg, var(--r95-title-lit) 0%, var(--r95-title) 100%);
  color: var(--r95-title-text);
  font-weight: 700; font-size: 12px;
  padding: 3px 4px 3px 6px;
}
.r95-page-titlebar .grow { flex: 1; }
.r95-page-controls { display: flex; gap: 2px; }
.r95-page-controls a, .r95-page-controls button {
  width: 18px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--r95-face); color: var(--color-text);
  border: 2px solid;
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
  font-size: 10px; line-height: 1; text-decoration: none; cursor: pointer;
  font-family: var(--font-body);
}
.r95-page-controls a:active, .r95-page-controls button:active {
  border-color: var(--r95-dark) var(--r95-light) var(--r95-light) var(--r95-dark);
}
.r95-page-body { padding: 12px; }
.r95-page-status {
  display: flex; gap: 8px;
  border-top: 1px solid var(--r95-light);
  padding: 3px 6px; font-size: 11px;
  color: var(--color-text);
}
.r95-page-status > span {
  border: 1px solid;
  border-color: var(--r95-shadow) var(--r95-light) var(--r95-light) var(--r95-shadow);
  padding: 1px 6px;
}
.r95-page-status .grow { flex: 1; }

/* --- form layout inside a window ------------------------------------------ */
/* The grouped box with a notched legend is the single most recognisable
   Win95 form device, and it is already the vocabulary Cost Estimation uses
   (.r95-group / .r95-legend), so forms converted here match that module
   rather than merely rhyming with it. */
.r95-group {
  border: 2px groove var(--r95-legend);
  padding: 12px 14px 14px;
  margin: 0 0 14px;
}
.r95-legend {
  font-size: 12px;
  font-weight: 700;
  padding: 0 4px;
}
.r95-row {
  display: grid;
  grid-template-columns: 170px minmax(0, 1fr);
  align-items: start;
  gap: 8px;
  margin-bottom: 8px;
}
.r95-row > label {
  font-size: 12px;
  padding-top: 4px;
}
.r95-row .input { width: 100%; }
.r95-check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; margin-bottom: 8px;
}
.r95-err { font-size: 11px; color: #800000; margin-top: 3px; }
.r95-buttons {
  display: flex; gap: 6px; justify-content: flex-end;
  padding-top: 4px;
}
.r95-buttons .btn { min-width: 84px; }

@media (max-width: 720px) {
  .r95-row { grid-template-columns: 1fr; }
  .r95-row > label { padding-top: 0; }
}


/* --- the action button ------------------------------------------------- */
/* SAP paints the button that DOES something in yellow and leaves every
   other control the same pale blue, which is why "New Estimate..." reads
   as the thing to press without anyone being told. Every "+ New" in the
   ERP now gets the same treatment, so the eye learns one rule. */
.btn-primary {
  background: var(--r95-action);
  border-color: var(--r95-light) var(--r95-action-edge) var(--r95-action-edge) var(--r95-light);
  color: var(--r95-ink);
  font-weight: 700;
}
.btn-primary:active {
  border-color: var(--r95-action-edge) var(--r95-light) var(--r95-light) var(--r95-action-edge);
}

/* --- a "+ New" opens as a floating window ------------------------------- */
/* The client asked for this explicitly: pressing New should put a window in
   front of you, not take you to another screen.

   Done with layout rather than JavaScript. The create screen is still its
   own URL with its own form post, so bookmarks, the back button, validation
   errors and every existing test keep working exactly as they did — it is
   presented as a dialog rather than reimplemented as one. Loading it over
   the list by fetch would mean rebuilding error handling and redirects on
   fifty screens to gain nothing the eye can see. */
.r95-client:has(.r95-page-window.is-dialog) {
  /* The page behind a dialog dims, the way it does when Cost Estimation
     opens one on top of an estimate. */
  background:
    linear-gradient(rgba(22, 50, 79, .28), rgba(22, 50, 79, .28)),
    var(--r95-panel);
}
.r95-page-window.is-dialog {
  /* Two widths, chosen per screen, because sizing to content turned out
     worse than either: fit-content made a line-items table push the whole
     window off the right of the page, where margin:auto cannot pull an
     overflowing box back. A record form is narrow; a document with lines
     is wide. There is no third case. */
  width: min(620px, calc(100% - 40px));
  margin: 40px auto;
  box-shadow: 3px 3px 0 rgba(22, 50, 79, .35), 0 10px 34px rgba(22, 50, 79, .25);
}
.r95-page-window.is-dialog.is-wide {
  width: min(1180px, calc(100% - 40px));
}
/* A dialog's body is the pale blue FACE, not white. The sunken bevel on a
   field is a shadow on its top-left and a white highlight on its
   bottom-right — put a white field on a white body and that highlight
   vanishes, so the field reads as two stray lines instead of a well. The
   working areas stay white: lists, grids, and the field interiors. */
.r95-page-window.is-dialog .r95-page-body { background: var(--r95-face); }

/* --- window chrome on the approved palette -------------------------------- */
.r95-page-window {
  background: var(--r95-face);
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
}
.r95-page-controls a,
.r95-page-controls button {
  background: var(--r95-face);
  color: var(--r95-ink);
  border-color: var(--r95-light) var(--r95-dark) var(--r95-dark) var(--r95-light);
}
.r95-page-status { background: var(--r95-face); color: var(--r95-ink); }
.r95-legend { color: var(--r95-ink); }
.text-muted { color: var(--r95-muted) !important; }

/* --- the pop-out host ------------------------------------------------- */
/* A form opens ON TOP of the list rather than in place of it. Styling the
   create page as a window was not the same thing: the list vanished, which
   is a page wearing a title bar. */
.r95-popout-host {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(22, 50, 79, .35);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 20px; overflow: auto;
}
/* Must come AFTER the display:flex rule above and match its specificity,
   or [hidden] loses and the overlay shows on every page load. The command
   palette in base_sidebar carries the same note for the same reason. */
.r95-popout-host[hidden] { display: none; }

.r95-popout-host .r95-page-window {
  margin: 0;
  box-shadow: 4px 4px 0 rgba(22, 50, 79, .35), 0 16px 48px rgba(22, 50, 79, .35);
}
.r95-page-window.is-dialog:has(.field) { width: min(620px, 100%); }
.r95-popout-host .r95-page-window.is-dialog.is-wide { width: min(1180px, 100%); }

/* ---- required fields -------------------------------------------------
 * Set on the label by CompanyScopedFormMixin, so every form in the ERP
 * gets it without a template knowing. Decorative and aria-hidden: the
 * input already carries the HTML required attribute, which is what a
 * screen reader announces.
 */
.req {
  color: #b02a2a;
  font-weight: 700;
  margin-left: 1px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .req { color: #e08c8c; }
}

/* ---- a form in a pop-out window is COMPACT ---------------------------
 * The windows were running past the bottom of the screen, so a form you
 * had just opened needed scrolling before you could see the Save button.
 * Two things fix that and both are needed.
 *
 * The body scrolls INSIDE the window rather than the window growing past
 * the viewport, so the title bar and the buttons stay put wherever you
 * are in a long form.
 *
 * And the whole thing is tightened: a 34px heading and 20px gutters are
 * right on a full page and wasteful in a dialog, where every pixel spent
 * on air is a field pushed off screen.
 *
 * Scoped to a window that CONTAINS A FIELD, not to pop-outs: the same
 * form is reached both ways - from a list it opens as a pop-out, from
 * Ctrl+K or an Edit link it opens as a page - and it looked like two
 * different screens depending on which. The list screens and the
 * detail pages have no .field and are untouched.
 */
.r95-popout-host .r95-page-window.is-popout {
  max-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
}
.r95-popout-host .r95-page-window.is-popout > .r95-page-body {
  overflow-y: auto;
  min-height: 0;
}

/* heading: a dialog already says what it is in its title bar */
.r95-page-window:has(.field) h1 { font-size: 20px !important; margin-bottom: 4px !important; }
.r95-page-window:has(.field) h4 { font-size: 14px !important; }
.r95-page-window:has(.field) .hr { margin: 10px 0 14px !important; }

/* fields: shorter rows, tighter gutters, smaller labels */
.r95-page-window:has(.field) .field { margin-bottom: 0; }
.r95-page-window:has(.field) .field label,
.r95-page-window:has(.field) label {
  font-size: 11.5px;
  margin-bottom: 2px;
  display: block;
}
.r95-page-window:has(.field) .input,
.r95-page-window:has(.field) input[type="text"],
.r95-page-window:has(.field) input[type="number"],
.r95-page-window:has(.field) input[type="date"],
.r95-page-window:has(.field) input[type="email"],
.r95-page-window:has(.field) select {
  height: 26px;
  padding: 1px 6px;
  font-size: 12.5px;
}
.r95-page-window:has(.field) textarea {
  font-size: 12.5px;
  padding: 3px 6px;
}
/* the help text under a field is reference, not reading matter */
.r95-page-window:has(.field) .text-muted { font-size: 11px !important; line-height: 1.35; }

/* the field grid: narrower gutters, and never fewer than two columns
   where the template asked for three — three 26px rows beat one tall one */
.r95-page-window:has(.field) [style*="grid-template-columns"] {
  gap: 10px 14px !important;
}
/* line-item tables inside a dialog */
.r95-page-window:has(.field) table.table th,
.r95-page-window:has(.field) table.table td {
  padding: 3px 6px;
  font-size: 12px;
}

/* ---- "this could not be saved" --------------------------------------
 * Modal on purpose. A refusal you can ignore is how somebody believes a
 * thing saved when it did not — the same reasoning that makes an error
 * message wait to be dismissed while a success closes itself.
 */
.zg-error-host {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(22, 50, 79, .45);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.zg-error-box {
  width: min(460px, 100%);
  background: var(--r95-face);
  border-top: 2px solid var(--r95-light);
  border-left: 2px solid var(--r95-light);
  border-right: 2px solid var(--r95-dark);
  border-bottom: 2px solid var(--r95-dark);
  box-shadow: 4px 4px 0 rgba(22, 50, 79, .35);
  padding: 3px;
}
.zg-error-title {
  background: #b02a2a; color: #fff;
  font-size: 12.5px; font-weight: 700;
  padding: 3px 8px;
}
.zg-error-body {
  background: var(--r95-panel);
  padding: 12px 14px; margin-top: 3px;
  max-height: 46vh; overflow-y: auto;
}
.zg-error-body ul { margin: 0; padding-left: 18px; }
.zg-error-body li { font-size: 13px; line-height: 1.5; margin-bottom: 5px; }
.zg-error-body li:last-child { margin-bottom: 0; }
.zg-error-foot {
  display: flex; justify-content: flex-end;
  padding: 8px; background: var(--r95-face);
}

/* Two columns in a dialog.
 *
 * Most form templates stack their fields in a single flex column, which
 * is fine on a full page and makes a dialog enormous: eight fields at
 * one per row ran past the bottom of the screen before you reached Save.
 * Turning that column into a grid halves the height for nothing.
 *
 * !important because the stack is an inline style on the wrapper, and
 * :has(> .field) rather than a class because the wrapper has none — the
 * templates were written before there was any reason to name it.
 */
.r95-page-window:has(.field) form > div:has(> .field) {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  gap: 8px 14px !important;
  align-items: start;
}
/* a text area needs the width more than it needs a neighbour */
.r95-page-window:has(.field) .field:has(textarea) { grid-column: 1 / -1; }
.r95-page-window:has(.field) textarea { min-height: 48px; }

/* a plain dialog gets a little wider now it holds two columns */
.r95-page-window.is-dialog:has(.field) { width: min(700px, 100%); }
