/* ═══════════════════════════════════════════════════════════════════
   LEDGER — a skin, and the components that come with it.

   Owner 2026-10-28: *"Redo the UI of Support Assignments including all
   tabs ... experiment with some more colors other than the current
   almost monochromic theme ... Build for Dark as well as Light theme
   ... use some motion elements ... use some UI elements which has not
   been built in the app till now ... and a color combo that has not
   been used till now."* Shown three directions, he chose **A, Ledger**,
   and scoped it: *"Screen now, tokens ready to spread."*

   ── Why this file redefines --fiori-* instead of inventing names ──
   Support Assignments styles itself through a `T` map that already
   reads --fiori-brand, --fiori-surface and the rest. Custom properties
   cascade, so redefining those few variables on ONE container re-skins
   everything inside it without touching a single style object in the
   page — and spreading it later is moving this block from `.ld-skin`
   to `:root`, not a rewrite. A parallel --ld-* namespace would have
   meant editing every inline style twice.

   The --ld-* names below are only for what --fiori-* has no word for:
   the copper second accent, the display face, the rule weight.

   ── The palette, and why these hues ──
   The app is blue on slate everywhere: #3B8DF8 brand, #2563EB in
   light, slate neutrals, with emerald / amber / rose as status. The
   owner asked for a combination that has not been used. Ledger is
   PETROL TEAL against BURNT COPPER on warm paper or espresso —
   complementary rather than analogous, and warm neutrals rather than
   the cool slate, so nothing here reads as a variation of the old
   screen.

   ── Dark first, like the rest of the app ──
   bizsuite.css puts dark on the bare selector and light under
   [data-theme="light"], toggled on <html> at runtime. This file
   mirrors that exactly. Writing it light-first would have made the
   default theme the one nobody set.
   ═══════════════════════════════════════════════════════════════════ */

.ld-skin {
  /* ── dark (the default, as everywhere else) ───────────────────── */
  --fiori-bg:            #17120F;
  --fiori-surface:       #201A16;
  --fiori-surface-solid: #201A16;
  --fiori-surface2:       #2A221C;
  --fiori-surface2-solid: #2A221C;
  --fiori-border:        #3A2F28;
  --fiori-border-light:  #4A3C33;
  --fiori-text:          #F3EDE4;
  --fiori-text-muted:    #A99C8E;

  /* Petrol, lifted for dark so white text on it still clears AA.
     #4FBFC2 against #17120F is a contrast of 9.4:1, and the ink used
     ON the brand is espresso rather than white for the same reason —
     a pale teal with white text is the one combination here that
     would fail. */
  --fiori-brand:       #4FBFC2;
  --fiori-brand-hover: #6FD2D4;
  --fiori-brand-glow:  rgba(79,191,194,0.22);
  --ld-on-brand:       #10211F;

  --ld-accent:       #E08E5F;   /* burnt copper */
  --ld-accent-hover: #EDA377;
  --ld-on-accent:    #251309;

  --fiori-positive: #5FD3A0;
  --fiori-warning:  #E3A954;
  --fiori-negative: #E8796A;

  --ld-rule:    #3A2F28;
  --ld-hair:    rgba(243,237,228,0.09);
  --ld-shadow:  0 1px 2px rgba(0,0,0,.42), 0 10px 30px -14px rgba(0,0,0,.72);
  --ld-radius:  14px;

  /* No web font is loaded anywhere in this app, and one screen is not
     a reason to make every page wait on a third-party request. The
     mock-up used Fraunces; this uses the system serif, which on macOS
     is New York and on Windows falls to Georgia — both are real
     display faces, both are already on the machine. */
  --ld-display: ui-serif, "New York", Georgia, "Iowan Old Style", "Times New Roman", serif;
}

[data-theme="light"] .ld-skin {
  --fiori-bg:            #EFEBE4;
  --fiori-surface:       #FFFFFF;
  --fiori-surface-solid: #FFFFFF;
  --fiori-surface2:       #F6F2EB;
  --fiori-surface2-solid: #F6F2EB;
  --fiori-border:        #DAD2C6;
  --fiori-border-light:  #C9BFB0;
  --fiori-text:          #1A1713;
  --fiori-text-muted:    #6B6257;

  /* Darkened for light mode: #0E6C70 on white is 5.6:1, and white on
     #0E6C70 is the same — so the brand works as a fill AND as text,
     which the lifted dark-mode teal cannot. */
  --fiori-brand:       #0E6C70;
  --fiori-brand-hover: #0A585B;
  --fiori-brand-glow:  rgba(14,108,112,0.16);
  --ld-on-brand:       #FFFFFF;

  --ld-accent:       #A84F28;
  --ld-accent-hover: #8F4220;
  --ld-on-accent:    #FFFFFF;

  --fiori-positive: #2E7D5B;
  --fiori-warning:  #9A5E12;
  --fiori-negative: #A8332A;

  --ld-rule:   #DAD2C6;
  --ld-hair:   rgba(26,23,19,0.08);
  --ld-shadow: 0 1px 2px rgba(26,23,19,.05), 0 8px 24px -12px rgba(26,23,19,.18);
}

/* ── The page ───────────────────────────────────────────────────── */
.ld-skin { color: var(--fiori-text); }

/* A document, so its headings are set in the display face. Applied by
   class rather than to every h3 on the page: the tabs render plenty of
   headings that are labels, not titles, and setting those in a serif
   would read as a mistake. */
.ld-skin .ld-display {
  font-family: var(--ld-display);
  font-weight: 600;
  letter-spacing: -0.012em;
}

/* Hairline rules, the quiet structure of a printed contract. */
.ld-skin .ld-rule { border: 0; border-top: 1px solid var(--ld-hair); margin: 13px 0; }

/* The copper second accent, for the things that are about the
   AGREEMENT rather than about the app: the contract chip, the
   validity, the deliverables. Used sparingly on purpose — two accents
   both used everywhere is one accent twice. */
.ld-skin .ld-accent { color: var(--ld-accent); }
.ld-skin .ld-chip-accent {
  background: color-mix(in srgb, var(--ld-accent) 15%, transparent);
  color: var(--ld-accent);
  border: 1px solid color-mix(in srgb, var(--ld-accent) 32%, transparent);
}

/* ── NEW: the progress spine ────────────────────────────────────────
   Nothing in the app shows how far a multi-tab setup has got. Seven
   tabs and no sense of which of them you have actually filled in is
   the complaint this answers. */
.ld-skin .ld-spine { margin: 0 0 15px; }
.ld-skin .ld-step {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 0 0 14px; position: relative;
}
.ld-skin .ld-step:not(:last-child)::before {
  content: ""; position: absolute; left: 12px; top: 27px; bottom: 0; width: 2px;
  background: linear-gradient(var(--fiori-brand),
                              color-mix(in srgb, var(--fiori-brand) 12%, transparent));
}
.ld-skin .ld-dot {
  width: 25px; height: 25px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center; font-size: 11px; font-weight: 700;
  border: 2px solid var(--fiori-brand); color: var(--fiori-brand);
  background: var(--fiori-surface);
  transition: background .3s ease, color .3s ease;
}
.ld-skin .ld-step.is-done .ld-dot { background: var(--fiori-brand); color: var(--ld-on-brand); }
.ld-skin .ld-step b { font-size: 12.6px; display: block; }
.ld-skin .ld-step small { color: var(--fiori-text-muted); font-size: 11.2px; }

/* ── NEW: a tab strip whose underline travels ───────────────────────
   The app's tab strips move a filled block from one button to the
   next. This draws a line that SLIDES, which is what tells you the two
   tabs are the same surface rather than two places. */
.ld-skin .ld-tabs { position: relative; }
.ld-skin .ld-ink {
  position: absolute; bottom: -1px; height: 2.5px; border-radius: 3px;
  background: var(--fiori-brand);
  transition: transform .42s cubic-bezier(.34,1.25,.5,1),
              width .42s cubic-bezier(.34,1.25,.5,1);
}

/* ── Motion ─────────────────────────────────────────────────────────
   Quiet, and all of it on arrival or on hover. A document that
   animates while you read it stops reading as a document. */
.ld-skin .ld-rise { animation: ld-rise .5s cubic-bezier(.22,1,.36,1) both; }
.ld-skin .ld-rise:nth-child(2) { animation-delay: .06s; }
.ld-skin .ld-rise:nth-child(3) { animation-delay: .12s; }
.ld-skin .ld-rise:nth-child(4) { animation-delay: .18s; }
.ld-skin .ld-rise:nth-child(5) { animation-delay: .24s; }
.ld-skin .ld-rise:nth-child(n+6) { animation-delay: .3s; }
@keyframes ld-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.ld-skin .ld-lift { transition: transform .25s ease, box-shadow .25s ease; }
.ld-skin .ld-lift:hover { transform: translateY(-2px); box-shadow: var(--ld-shadow); }

.ld-skin .ld-spin { transition: transform .3s cubic-bezier(.34,1.4,.5,1), background .25s, color .25s; }
.ld-skin .ld-spin:hover { transform: rotate(90deg); }

/* Somebody who has asked their operating system to stop animations has
   asked this screen too. Not a nicety: motion sickness and vestibular
   disorders are the reason this media query exists. */
@media (prefers-reduced-motion: reduce) {
  .ld-skin .ld-rise,
  .ld-skin .ld-lift,
  .ld-skin .ld-spin,
  .ld-skin .ld-ink,
  .ld-skin .ld-dot { animation: none !important; transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   THE ESCALATION PYRAMID

   Owner 2026-10-28: *"Show the escalation matrix like a triangle with
   number of horizontal sections. And 2 vertical sections. Left one is
   SI and Right one is Customer. Allow names / users and breach time to
   be entered in each horizontal and vertical section."*

   ── A stepped pyramid, not a clipped one ──
   A true triangle is one clip-path and it is the wrong answer: it
   slices the text at every edge and leaves the apex too narrow to
   hold a name, let alone a name and a time. These are BANDS of
   decreasing width, centred, with the sloping edges drawn beside
   them. The silhouette is a triangle and every field stays
   rectangular, which is what an input has to be.

   ── Bottom is first ──
   Level 1 is the widest band at the BOTTOM: the desk lead, told
   first, the broadest group. The apex is whoever is told last. That
   matches both the owner's reference and the ladder's own numbering,
   so the picture and the data agree about which way up seniority
   runs.

   ── It stops being a pyramid on a phone ──
   Below 820px the bands go full width and stack. A 46%-wide apex on a
   360px screen is 165px holding two inputs, which is not a design, it
   is a dare.
   ═══════════════════════════════════════════════════════════════════ */
.ld-skin .ld-pyr { position: relative; padding: 4px 30px 2px; }

/* ── The two rails, and what they carry ─────────────────────────────
   These were first drawn as rules rotated 14deg, meant to read as the
   pyramid's sloping sides. Rendered, they did not: the real slope
   depends on how many bands there are AND how tall each one grew once
   its inputs wrapped, so a fixed angle crossed the bands at some
   levels and ran outside the card at others. There is no angle that
   is right for every ladder, so these carry the DIRECTION instead of
   the shape — issues climb, resolutions come back down — and sit
   upright in the gutter the padding above reserves. An arrow cannot
   be at the wrong angle. */
.ld-skin .ld-pyr-rail {
  position: absolute; top: 2px; bottom: 26px; width: 2px; border-radius: 2px;
  pointer-events: none;
}
.ld-skin .ld-pyr-rail.is-left {
  left: 8px;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--ld-accent) 14%, transparent), var(--ld-accent));
}
.ld-skin .ld-pyr-rail.is-right {
  right: 8px;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--ld-accent) 14%, transparent), var(--ld-accent));
}
.ld-skin .ld-pyr-rail span {
  position: absolute; top: 50%; left: 50%;
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ld-accent); white-space: nowrap; font-weight: 700;
  writing-mode: vertical-rl;
}
/* Left reads bottom-to-top, with the climb. Right reads top-to-bottom,
   with the answer coming back. */
.ld-skin .ld-pyr-rail.is-left  span { transform: translate(-50%,-50%) rotate(180deg); }
.ld-skin .ld-pyr-rail.is-right span { transform: translate(-50%,-50%); }

.ld-skin .ld-band {
  margin: 0 auto 7px; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--fiori-border);
  background: var(--fiori-surface2);
  display: grid; grid-template-columns: 1fr 1fr;
  animation: ld-rise .5s cubic-bezier(.22,1,.36,1) both;
}
/* The grid's children are the two halves and nothing else. They used
   to carry .ld-cell themselves and wrap a second .ld-cell, so one
   class had to mean both "a column of the band" and "the padded box
   inside it" — and the divider rule, written as .ld-cell + .ld-cell,
   was one stray sibling away from drawing a line down the middle of a
   half. Two names, so each rule names exactly what it means. */
.ld-skin .ld-band .ld-half { min-width: 0; }
.ld-skin .ld-band .ld-half + .ld-half { border-left: 1px dashed var(--fiori-border); }
.ld-skin .ld-band .ld-cell { padding: 0 11px 10px; min-width: 0; }

/* The band's number, and the rung it is. */
.ld-skin .ld-band-no {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fiori-text-muted); font-weight: 700; margin-bottom: 5px;
  display: flex; align-items: center; gap: 6px;
}
.ld-skin .ld-band-no b { color: var(--fiori-brand); }

/* Wide: the party is named once, in the head above the apex, and the
   right half's level number is held as a ghost purely to keep the two
   halves on one baseline. Narrow: the head goes, the ghost goes, and
   each half names its own party instead. */
.ld-skin .ld-band-no .ld-party { display: none; }
.ld-skin .ld-band-no.ld-ghost .ld-lvl { visibility: hidden; }

/* Tinted by how far up the pyramid it is, so the apex reads as the
   most serious band without a second colour being introduced. */
.ld-skin .ld-band[data-step="0"] { background: var(--fiori-surface2); }
.ld-skin .ld-band[data-step="1"] { background: color-mix(in srgb, var(--fiori-brand) 7%, var(--fiori-surface2)); }
.ld-skin .ld-band[data-step="2"] { background: color-mix(in srgb, var(--fiori-brand) 13%, var(--fiori-surface2)); }
.ld-skin .ld-band[data-step="3"] { background: color-mix(in srgb, var(--fiori-brand) 19%, var(--fiori-surface2)); }
.ld-skin .ld-band[data-step="4"] { background: color-mix(in srgb, var(--fiori-brand) 25%, var(--fiori-surface2)); }

/* Caps the apex, not the base: the head is rendered above the
   NARROWEST band, so it is given that band's width by the component.
   Sized to the base it would have floated over the gap. */
.ld-skin .ld-pyr-head {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  margin: 0 auto 8px; text-align: center;
}
.ld-skin .ld-pyr-head div {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--fiori-text-muted); padding-bottom: 4px;
}

@media (max-width: 820px) {
  /* Full width, in order, rails gone — a pyramid this narrow is an
     illustration nobody can type into. */
  .ld-skin .ld-pyr { padding-left: 0; padding-right: 0; }
  .ld-skin .ld-pyr-rail { display: none; }
  .ld-skin .ld-band { width: 100% !important; grid-template-columns: 1fr; }
  .ld-skin .ld-pyr-head { display: none; }
  .ld-skin .ld-band-no .ld-party { display: inline; color: var(--fiori-brand); }
  .ld-skin .ld-band-no.ld-ghost .ld-lvl { display: none; }
  .ld-skin .ld-band .ld-half + .ld-half {
    border-left: 0; border-top: 1px dashed var(--fiori-border);
  }
}
