/* HARPS Version 2 — application shell (top navigation + side rail).
 *
 * Values taken from Figma:
 *   Navigation  5088:21035  (56px tall, #4045c2, 24px inset)
 *   Sidebar     5147:119189 (64px collapsed) / 5090:26680 (200px expanded)
 *
 * V2-only: loaded from pages under /v2/, so Version 1 is unaffected.
 * Icons are the exported Figma assets in v2/assets/figma/.
 */

/* Pages that do not ship AR/AP's universal `* { margin: 0 }` still inherit
   the user-agent body margin (typically 8px). That inset is a white strip
   around the sticky topbar — left, top, and right — because html stays
   the default canvas colour while the bar is painted on body. Zeroing it
   here is the shell's job, not a per-page overlay. */
html, body {
  margin: 0;
  padding: 0;
}

:root {
  /* Figma: navigation/topbar/* and navigation/size/* */
  --v2-topbar-h: 56px;
  --v2-topbar-bg: #4045c2;
  --v2-topbar-text: #ffffff;
  --v2-topbar-pad-x: 24px;
  --v2-brand-gap: 8px;
  --v2-brand-mark-w: 32px;
  --v2-utilities-gap: 16px;

  /* Figma: Sidebar frame + nav-item/size/*
     Collapsed 5147:119189 (64px) and expanded 5090:26680 (200px) are one
     component; --v2-rail-w is the single width the shell lays out against, so
     the rail and the main column stay in step from one value.

     The two states do not share their metrics. Expanded is a 40px row on a
     4px rhythm inside 20/14 padding; collapsed is a 44px target on an 8px
     rhythm inside 17/9. The base tokens carry the expanded figures and the
     collapsed ones are named separately rather than overridden on the state
     selector, so switching the rail cannot drag the topbar's brand offset —
     derived below from the same tokens — along with it. */
  --v2-rail-w-collapsed: 64px;
  --v2-rail-w-expanded: 200px;
  --v2-rail-w: var(--v2-rail-w-collapsed);
  --v2-rail-pad-y: 20px;
  --v2-rail-pad-x: 14px;
  --v2-rail-gap: 4px;
  --v2-rail-pad-y-collapsed: 17px;
  --v2-rail-pad-x-collapsed: 9px;
  --v2-rail-gap-collapsed: 8px;
  --v2-navitem-size-collapsed: 44px;
  --v2-rail-border: #e5e5eb;
  --v2-navitem-size: 40px;
  --v2-navitem-radius: 6px;
  --v2-navitem-active-bg: #e2e3f2;
  --v2-navitem-hover-bg: #f2f3f7;
  --v2-icon-size: 20px;
  --v2-focus-ring: #4045c2;

  /* Gutters around the main column, shared by every V2 page so a list view and
     a detail view sit on the same grid. Figma 1440x900 places the content
     between a 25px left and 33px right margin, 20px below the bar. */
  --v2-page-pad-top: 20px;
  --v2-page-pad-right: 33px;
  --v2-page-pad-bottom: 12px;
  --v2-page-pad-left: 25px;

  /* Left inset that puts the Disney mark's centre on the rail icon centreline.
     Measured against the collapsed rail, which is the state the bar is read
     with: it centres its icons at (9 + 44 / 2) = 31px, and the mark's artwork
     fills its 32x28 viewBox edge to edge, so its centre is its own midpoint.
     Solving mark-left + mark-width / 2 = 31 gives 15px. Derived rather than
     hard-coded so it tracks any rail token change, and read from the collapsed
     tokens specifically so expanding the rail never shifts the mark.
     Figma composes the same offset by placing the Navigation instance at
     x=-6 against its own 24px padding (5099:59848). */
  --v2-topbar-pad-left: calc(
    var(--v2-rail-pad-x-collapsed) + var(--v2-navitem-size-collapsed) / 2
      - var(--v2-brand-mark-w) / 2
  );
}

/* ═══ TOP NAVIGATION ═══════════════════════════════════════════════════ */
.v2-topbar {
  position: sticky;
  top: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  height: var(--v2-topbar-h);
  /* Right inset stays at the Figma 24px so the utilities cluster does not move. */
  padding: 0 var(--v2-topbar-pad-x) 0 var(--v2-topbar-pad-left);
  background: var(--v2-topbar-bg);
  box-sizing: border-box;
}

.v2-brand {
  display: flex;
  align-items: center;
  gap: var(--v2-brand-gap);
  flex-shrink: 0;
  text-decoration: none;
}

.v2-brand-mark {
  display: block;
  width: 32px;
  height: 28px;
  flex-shrink: 0;
}

/* The page-level @font-face for "MultiPlane" lists only local() sources. On a
   machine without the font installed that face fails, and because it spans
   `font-weight: 400 700` it shadows the URL-backed Bold face for weight 700 —
   the wordmark silently rendered in the fallback stack. Binding the shipped
   Bold file to its own family sidesteps the poisoned one and keeps the fix
   inside the header instead of changing page-wide font resolution. */
@font-face {
  font-family: "MultiPlane Display";
  src: url("../../assets/fonts/MultiplaneTWDC-Bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Medium is the heading/lg weight used by the Accounts Receivable title
   (Figma 5091:57953). Same family, so both header marks resolve through one
   set of URL-backed faces. */
@font-face {
  font-family: "MultiPlane Display";
  src: url("../../assets/fonts/MultiplaneTWDC-Medium.otf") format("opentype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* Figma 5099:61809: MultiplaneTWDC Display Bold 18/24, white.
   `!important` is required — #harps-typography-stabilization forces
   `font-family: var(--font-family) !important` onto every span/div, and
   ads-theme.css redefines that token as Open Sans. */
.v2-brand-name {
  font-family: "MultiPlane Display", "MultiPlane", var(--font-family, sans-serif) !important;
  font-size: 18px;
  line-height: 24px;
  font-weight: 700;
  color: var(--v2-topbar-text);
  white-space: nowrap;
}

/* Figma uses two flex spacers between brand and utilities. */
.v2-topbar-spacer {
  flex: 1 0 0;
  min-width: 0;
}

.v2-utilities {
  display: flex;
  align-items: center;
  gap: var(--v2-utilities-gap);
  flex-shrink: 0;
}

.v2-util {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  border-radius: 4px;
  transition: opacity 0.1s ease;
}

.v2-util:hover {
  opacity: 0.75;
}

.v2-util:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

.v2-util-icon {
  display: block;
  width: var(--v2-icon-size);
  height: var(--v2-icon-size);
}

/* Avatar hosts the existing profile dropdown, so it stays position:relative. */
.v2-avatar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  cursor: pointer;
}

.v2-avatar img {
  display: block;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
}

.v2-avatar:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

/* ═══ SIDE NAVIGATION RAIL ═════════════════════════════════════════════ */
.v2-rail {
  position: sticky;
  top: var(--v2-topbar-h);
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: var(--v2-rail-gap);
  align-items: flex-start;
  width: var(--v2-rail-w);
  min-height: calc(100vh - var(--v2-topbar-h));
  padding: var(--v2-rail-pad-y) var(--v2-rail-pad-x);
  background: #ffffff;
  border-right: 1px solid var(--v2-rail-border);
  box-sizing: border-box;
  flex-shrink: 0;
}

.v2-rail-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--v2-navitem-size);
  height: var(--v2-navitem-size);
  border-radius: var(--v2-navitem-radius);
  flex-shrink: 0;
  text-decoration: none;
  background: transparent;
  transition: background 0.1s ease;
}

.v2-rail-item:hover {
  background: var(--v2-navitem-hover-bg);
}

.v2-rail-item:focus-visible {
  outline: 2px solid var(--v2-focus-ring);
  outline-offset: 1px;
}

.v2-rail-item[aria-current="page"] {
  background: var(--v2-navitem-active-bg);
}

/* Non-navigating rail entries still read as controls but aren't clickable. */
.v2-rail-item[aria-disabled="true"] {
  cursor: default;
}

/* Collapsed, the whole rail is one target for opening it — the icons, the gaps
   between them, and the empty run down to the toggle — so it all takes the
   pointer, including the entries that have nowhere to navigate. Expanded, only
   the items and the toggle do anything, and the default cursor says so. */
html[data-sidebar="collapsed"] .v2-rail,
html[data-sidebar="collapsed"] .v2-rail-item[aria-disabled="true"] {
  cursor: pointer;
}

.v2-rail-icon {
  display: block;
  width: var(--v2-icon-size);
  height: var(--v2-icon-size);
  flex: none;
}

/* Rail glyphs are painted as masks rather than shown as images, so their
   colour comes from the row's state instead of the fill baked into each
   exported SVG. `content` drops the bitmap; the mask re-draws the same file
   as a solid shape in currentColor. --v2-rail-icon-src is published per row
   by v2-sidebar.js. */
.v2-rail-icon[style*="--v2-rail-icon-src"] {
  content: "";
  background-color: currentColor;
  -webkit-mask: var(--v2-rail-icon-src) center / contain no-repeat;
  mask: var(--v2-rail-icon-src) center / contain no-repeat;
}

.v2-rail-item .v2-rail-icon { color: var(--ads-gray-200, #3b4347); }

/* Selected glyph. `has-active-child` covers the builds where Finance is a
   group toggle or flyout trigger, so the parent row carries the active
   treatment while the current page lives inside it. */
.v2-rail-item[aria-current="page"] .v2-rail-icon,
.v2-rail-item.has-active-child .v2-rail-icon,
.v2-rail-group.has-active-child > .v2-rail-group-toggle .v2-rail-icon {
  color: #4045c2;
}

/* ═══ SIDEBAR — COLLAPSED STATE — Figma 5147:119189 ════════════
   64px rail, 44x44 targets on an 8px rhythm, 20px glyphs, 6px radius and the
   same #e2e3f2 selected fill the expanded rows carry. Figma draws the frame
   with a 1px border down both sides; the shell only has the right one, so the
   same 9px padding sits inside the same 64px box. */
html[data-sidebar="collapsed"] .v2-rail {
  gap: var(--v2-rail-gap-collapsed);
  padding: var(--v2-rail-pad-y-collapsed) var(--v2-rail-pad-x-collapsed);
  align-items: center;
}

html[data-sidebar="collapsed"] .v2-rail-item {
  width: var(--v2-navitem-size-collapsed);
  height: var(--v2-navitem-size-collapsed);
}

/* ═══ SIDEBAR — EXPANDED STATE ═════════════════════════════════════════
   Figma 5090:26680: 200px rail, 172x40 items, 10/12 padding, 8px gap, 6px
   radius; rest label Open Sans 14/20 #3b4347, active label SemiBold #4045c2
   behind a 3x20 indicator. The same .v2-rail-item markup carries both states,
   so nothing here is duplicated per profile or per state. */
html[data-sidebar="expanded"] {
  --v2-rail-w: var(--v2-rail-w-expanded);
}

/* Label is always in the DOM so the accessible name survives collapsing. */
.v2-rail-label {
  display: none;
  flex: 1 1 auto;
  min-width: 0;
  /* Stated rather than inherited. Most rows are spans, but the Finance group
     header is a real <button> so it can toggle, and a button's text centres by
     default. The label grows to fill the row, so that default centred its text
     inside the grown box and pushed "Finance" ~21px right of every other
     label — an indent that came from the element type, not from any spacing
     rule. Anchoring the text here keeps one alignment for both element types. */
  text-align: left;
  font-family: "Open Sans", var(--font-family, sans-serif);
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  color: #3b4347;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

html[data-sidebar="expanded"] .v2-rail-item {
  width: 100%;
  justify-content: flex-start;
  gap: 8px;
  padding: 10px 12px;
}

html[data-sidebar="expanded"] .v2-rail-label { display: block; }

html[data-sidebar="expanded"] .v2-rail-item[aria-current="page"] .v2-rail-label {
  font-weight: 600;
  color: #4045c2;
}

/* 3x20 bar that only the active row shows; it sits before the icon and is
   inert so it never lands in the accessibility tree. */
.v2-rail-indicator {
  display: none;
  flex: none;
  width: 3px;
  height: 20px;
  border-radius: 2px;
  background: #4045c2;
}

html[data-sidebar="expanded"] .v2-rail-item[aria-current="page"] .v2-rail-indicator {
  display: block;
}

/* ═══ FINANCE GROUP — VERSION 2.0-A ONLY (Figma 5109:66098) ════════════
   Accounts Payable / Accounts Receivable / Settings render as nested
   text-only rows under one expandable "Finance" parent instead of their own
   top-level rail icons. The parent row reuses `.v2-rail-item` (so it gets
   the same 40px sizing, hover, focus-visible and collapsed/expanded
   treatment as every other rail row for free) plus this group-specific
   layer for the chevron, the nested list and the "active parent" state. */
.v2-rail-group {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.v2-rail-group-toggle {
  cursor: pointer;
}

/* The chevron reports the section's state, the same convention every other
   disclosure control in the build follows: down while closed, up while open.
   It used to sit at a fixed -90deg — pointing right in both states — which
   left the only visual answer to "is this open?" being whether the children
   happened to be on screen. Rotation keys off the button's own
   `aria-expanded` rather than a class on its parent: it is the same value
   assistive tech reads, so the arrow and the announced state cannot disagree,
   and the pseudo-element restyles reliably because the attribute changes on
   the element that owns it. */
html[data-sidebar="expanded"] .v2-rail-group-toggle::after {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  margin-left: auto;
  background-color: currentColor;
  transform: rotate(0deg);
  transition: transform 0.1s ease;
  -webkit-mask: url("figma/icon-chevron-down.svg") center / contain no-repeat;
  mask: url("figma/icon-chevron-down.svg") center / contain no-repeat;
}

html[data-sidebar="expanded"] .v2-rail-group-toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

/* Finance is a section header, not a destination. It takes the active colour
   but never the selected background or the indicator bar: those two mark which
   page you are on, and the page you are on is always one of the children. The
   parent used to claim both, which put two rows in the selected state at once
   and left the bar pointing at a row that is not a route.

   Coloured while the section is open, and — independent of open state — while
   the current route lives inside it, so collapsing the list while still on
   Accounts Payable does not make Finance look inactive. */
.v2-rail-group.is-open > .v2-rail-group-toggle .v2-rail-icon,
.v2-rail-group.has-active-child > .v2-rail-group-toggle .v2-rail-icon {
  color: #4045c2;
}

html[data-sidebar="expanded"] .v2-rail-group.is-open > .v2-rail-group-toggle .v2-rail-label,
html[data-sidebar="expanded"] .v2-rail-group.has-active-child > .v2-rail-group-toggle .v2-rail-label {
  font-weight: 600;
  color: #4045c2;
}

/* The chevron is a mask painted with `currentColor`, and the rule above colours
   the label element rather than the button, so the arrow stayed dark while the
   icon and label went blue. Painting it on the same two conditions keeps the
   three parts of the row in agreement. Colour only — size, position and
   rotation are left to the rules that own them. */
html[data-sidebar="expanded"] .v2-rail-group.is-open > .v2-rail-group-toggle::after,
html[data-sidebar="expanded"] .v2-rail-group.has-active-child > .v2-rail-group-toggle::after {
  background-color: #4045c2;
}

.v2-rail-subitems {
  display: none;
  flex-direction: column;
  width: 100%;
}

html[data-sidebar="expanded"] .v2-rail-group.is-open > .v2-rail-subitems {
  display: flex;
}

/* Text-only, no icon — Figma indents these to x=24 inside the 200px rail
   (12px item padding + 12px extra), full row height for a real click target
   even without an icon. */
.v2-rail-subitem {
  display: flex;
  align-items: center;
  /* Positioning context for the active bar below. */
  position: relative;
  width: 100%;
  min-height: var(--v2-navitem-size);
  padding: 10px 12px 10px 24px;
  border-radius: var(--v2-navitem-radius);
  box-sizing: border-box;
  font-family: "Open Sans", var(--font-family, sans-serif);
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  color: #3b4347;
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background 0.1s ease;
}

.v2-rail-subitem:hover {
  background: var(--v2-navitem-hover-bg);
}

.v2-rail-subitem:focus-visible {
  outline: 2px solid var(--v2-focus-ring);
  outline-offset: 1px;
}

/* Resting colour, restated against the current page's own rule so a child that
   is merely visible cannot read as selected. `Accounts Payable` was rendering
   in the active indigo whenever the section was open — the only thing telling
   you which of the three you were actually on was the background. */
.v2-rail-subitem:not([aria-current="page"]) {
  font-weight: 400;
  color: #3b4347;
}

/* "You are here", not "press me". The full-strength active fill made the row
   read as a button sitting inside the menu; the bar and the colour already say
   where you are, so the background only needs to be present, not loud. Height,
   padding and radius are untouched, so the row keeps its place in the rhythm. */
.v2-rail-subitem[aria-current="page"] {
  background: rgba(64, 69, 194, 0.06);
  /* Square, so the tinted row reads as a band of the menu rather than a card
     floating in it — and so it matches 2.0-b and 2.0-c. */
  border-radius: 0;
  font-weight: 600;
  color: #4045c2;
}

/* The 3x20 active bar, matching the one top-level rows use. It lives on the
   child because the child is the route. Placed at the parent's indicator
   column rather than the row edge, so the marker sits in one vertical line
   whether the current page is a top-level row or a Finance child. */
.v2-rail-subitem[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 20px;
  border-radius: 2px;
  background: #4045c2;
}

.v2-rail-subitem[aria-disabled="true"] {
  cursor: default;
}

/* ═══ SIDEBAR TOGGLE — Figma 5090:26710 ════════════════════════════════ */
.v2-rail-toggle-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
  margin-top: auto;
  padding-bottom: 4px;
}

.v2-rail-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: #f5f5f7;
  cursor: pointer;
}

.v2-rail-toggle:hover { background: #e9e9ee; }

.v2-rail-toggle:focus-visible {
  outline: 2px solid var(--v2-focus-ring);
  outline-offset: 2px;
}

.v2-rail-toggle img {
  display: block;
  width: 16px;
  height: 16px;
}

/* Collapsed points the caret outward to mean "expand". */
html[data-sidebar="collapsed"] .v2-rail-toggle img { transform: rotate(180deg); }
html[data-sidebar="collapsed"] .v2-rail-toggle-row { justify-content: center; }

/* Width is the only animated property; labels simply appear. */
.v2-rail,
.page-content {
  transition: width 160ms ease, flex-basis 160ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .v2-rail,
  .page-content {
    transition: none;
  }
}

/* ═══ SHELL LAYOUT ═════════════════════════════════════════════════════ */
/* The rail sits beside the page content, both below the sticky topbar.
   The base rule still assumes the old 48px bar; retarget it to 56px. */
.page-shell {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - var(--v2-topbar-h));
}

/* The main column beside the rail. `min-width: 0` is what stops a wide child
   from pushing the column past the viewport and giving the page a horizontal
   scrollbar — flex items default to min-width:auto and refuse to shrink below
   their content. */
.page-content {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--v2-page-pad-top) var(--v2-page-pad-right)
           var(--v2-page-pad-bottom) var(--v2-page-pad-left);
  box-sizing: border-box;
}

/* ═══ NAV CONTROL NORMALISATION ════════════════════════════════════════
   `.v2-rail-item` was authored when every rail row was an <a> or a <span>,
   so it never reset the two properties only a <button> carries. Once Finance
   became a real button — the flyout trigger in V2.0-b/V2.0-c and the group
   toggle in V2.0-a, both of which must be buttons for aria-expanded to mean
   anything — the user-agent stylesheet supplied `appearance: auto` and
   `border: 2px outset ButtonBorder`, painting a black rectangle around the
   icon. That is what the black box is: a native button border, not a focus
   ring, not an outline, and not the ADS selected state.

   Resetting on the shared class rather than on each button keeps every row
   identical whatever element it happens to be, and stops the next nav row
   that becomes a button from reintroducing this.

   The intended ADS states are untouched: `.v2-rail-item:hover`,
   `[aria-current="page"]`, `.has-active-child` and the active indicator all
   still come from their own rules above. Keyboard focus also still comes
   from the existing `.v2-rail-item:focus-visible` rule, which uses the ADS
   --v2-focus-ring token (#4045c2), never black. */
.v2-rail-item,
.v2-rail-toggle,
.v2-rail-group-toggle,
.v2-flyout-trigger,
.v2-flyout-group {
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  font: inherit;
  box-sizing: border-box;
}

/* Deliberately no background reset here. The rows already paint themselves —
   `.v2-rail-item` sets `background: transparent` and the selected/hover/
   has-active-child rules layer on top of that — so adding another background
   declaration below them in the file only fights the state styling and blanks
   out the ADS selected fill. The user-agent's buttonface never reaches these
   rows, so there is nothing left to reset. */

/* A pointer click leaves :focus on a button in every browser, so without
   this the ADS focus ring lingers as a rectangle after the user has already
   moved on. :focus-visible above still fires for keyboard users, so this
   removes the stale pointer artefact without weakening accessibility. */
.v2-rail-item:focus:not(:focus-visible),
.v2-rail-toggle:focus:not(:focus-visible),
.v2-rail-group-toggle:focus:not(:focus-visible),
.v2-flyout-trigger:focus:not(:focus-visible),
.v2-flyout-group:focus:not(:focus-visible),
.v2-flyout-item:focus:not(:focus-visible) {
  outline: none;
  box-shadow: none;
}

/* ═══ PROFILE MENU — LINK ROWS ═══════════════════════════════
   Every row in the profile menu is a <button>, except System Map, which is a
   real anchor because it actually goes somewhere. That single difference is
   enough for the ADS theme's own `html[data-theme="ads"] a` rule — a type and
   attribute selector — to outrank `.profile-dd-item` and repaint the row brand
   indigo with an underline, so one option read as a web link sitting among
   menu items.

   Scoped through the dropdown so it outranks that theme rule, and limited to
   colour and decoration: everything else the row needs — Open Sans 14/20, the
   44px height, the 18px inset, the flex alignment, the hover fill and the
   focus treatment — already comes from `.profile-dd-item` and is therefore
   shared with the buttons rather than restated here. Keeping the states in
   the same rule stops the theme repainting the link on hover or focus. */
.profile-dropdown a.profile-dd-item,
.profile-dropdown a.profile-dd-item:link,
.profile-dropdown a.profile-dd-item:visited,
.profile-dropdown a.profile-dd-item:hover,
.profile-dropdown a.profile-dd-item:focus,
.profile-dropdown a.profile-dd-item:focus-visible {
  color: #1f2937;
  text-decoration: none;
}
