/* ------ LOGO TOOL STYLES ------ */
/*
  Layer: app. A full-space tool, same chassis as the display ad preview: fixed-height
  shell, control bar pinned at the top, stage taking the rest.

  Space in the bar is bought the way ad-preview buys it — trimmed padding on native
  controls, a fixed-width number field, and whole labelled groups collapsed behind one
  dropdown trigger. Format and Settings are dropdowns for that reason: a segmented
  control and three inline switches cost about four times the width of two triggers.

  One deliberate exception to the tokens-only rule: the stage background, the swatch
  chips and the transparency checkerboard are set from brand EXPORT data (hex values the
  script reads out of the logo manifest), not from theme tokens. The stage is a preview
  of the exported file, so it must show the file's real colours — theming it would make
  the preview lie. Everything else here is tokens.
*/

/* -- Layout -- */
/*
  dvh, not vh: on mobile browsers vh ignores the retracting browser chrome, which
  pushed the stage readouts underneath it. overflow-y auto rather than hidden so the
  bar stays reachable at high zoom; since the merge the bar no longer wraps — items
  that do not fit move to its overflow menu (WCAG 1.4.10 via disclosure).
  ad-preview.css carried both bugs and was brought onto these same three lines when
  the bar component landed.
*/
.logo-tool-layout {
  display: flex;
  flex-direction: column;
  height: calc(100dvh - var(--top-nav-height));
  overflow-x: hidden;
  overflow-y: auto;
}

/* Empty state swaps via a state class rather than [hidden] on the flex children: init
   runs inside Barba's afterEnter, and changing an in-flow element's display while the
   transition settles is the reflow-flash pattern this repo avoids. */
.logo-tool-layout.is-empty > .logo-tool-stage,
.logo-tool-layout.is-empty > .logo-tool-footer {
  display: none;
}

/* The bar stays, stripped to its close. Every control that acts on a logo
   goes in the empty state — there is nothing for it to act on — but the
   control that leaves the page stays, because the empty state is where the
   reader most needs one. The overflow trigger hides too, or it would offer a
   menu of controls the state just hid. */
.logo-tool-layout.is-empty > .bar .bar-group,
.logo-tool-layout.is-empty > .bar .bar-overflow,
.logo-tool-layout.is-empty > .bar #lt-export,
.logo-tool-layout.is-empty > .bar #lt-export-options,
.logo-tool-layout.is-empty > .bar #lt-reset {
  display: none;
}

/* -- Control bar -- */
/* The bar is the .bar component (design-system.css section 41), which owns the
   flex row, the group and label classes, the actions cluster, the native-control
   squash and the fixed number-field width — all of which started life here and in
   ad-preview.css as two copies of the same thing. Only the unit suffix is still
   tool-specific; the empty state is handled by .is-empty above. */
.logo-tool-unit {
  color: var(--text-faded);
  font-size: var(--font-xs);
}

/* -- Colour panel -- */
/* A disclosure, not a menu: the row below the divider is a switch. dropdown.js only
   closes on clicks outside .dropdown-menu, so it stays operable while the panel is
   open. The colour rows are .dropdown-item and stay full-bleed, so their hover reaches
   the panel edge; only the switch row takes an inset. */
.logo-tool-settings-panel {
  gap: var(--space-m);
  padding-bottom: var(--space-m);
}

.logo-tool-settings-panel > .logo-tool-option-row {
  padding-inline: var(--space-m);
}

/* -- Export options panel -- */
/* The other half of the split export cluster (see the bar markup note). Unlike the
   colour panel it opens with an inset row rather than full-bleed items, so it takes
   padding on both block edges, not just the bottom. */
.logo-tool-export-panel {
  gap: var(--space-m);
  padding-block: var(--space-m);
}

.logo-tool-export-panel > .logo-tool-option-row {
  padding-inline: var(--space-m);
}

/* -- Width panel -- */
/* Same idea: the presets are .dropdown-item, the custom field is not, so it borrows the
   item inset rather than sitting flush to the panel edge. Row, not column — the option
   rows above stack a switch over its note, this one sets a field beside its unit. */
.logo-tool-width-panel .logo-tool-option-row {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-m) var(--space-m);
}

.logo-tool-option-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.logo-tool-option-row[hidden] {
  display: none;
}

/* -- Colour chip -- */
/*
  A miniature of the pairing: the logo colour as a dot on the background it was designed
  for. Appears in the Colour dropdown trigger and in each of its menu items. The two
  colours arrive inline from the manifest as --swatch-fill / --swatch-bg, because they
  are brand export data rather than theme values.

  Selection state is the menu item's own .is-active plus its check icon, and focus is the
  design system's standard item focus — so unlike the hidden-radio chip group this
  replaced, there is no custom indicator to get wrong.
*/
.logo-swatch-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 1.125rem;
  aspect-ratio: 1 / 1;
  background: var(--swatch-bg);
  border: var(--border-s) solid var(--border-faded);
  border-radius: var(--radius-xs);
}

.logo-swatch-chip::before {
  content: "";
  width: 55%;
  aspect-ratio: 1 / 1;
  background: var(--swatch-fill);
  border-radius: 50%;
}


/* -- Stage -- */
/*
  The viewport background is the export truth: the selected colour's real background, or
  the transparency checkerboard. It deliberately ignores the site theme — the bar
  themes, the artwork surface does not.
*/
.logo-tool-stage {
  position: relative;
  flex: 1 1 auto;
  /* A floor so the stage cannot be squeezed to nothing once the layout is allowed to
     scroll — at high zoom the bar takes the whole shell otherwise. */
  min-height: 16rem;
  overflow: hidden;
}

.logo-tool-stage[hidden] {
  display: none;
}

.logo-tool-viewport {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3xl) var(--space-2xl);
  background-color: var(--background-primary);
}

/* Fixed greys, not tokens: the checkerboard is the universal "no background here"
   convention and has to read the same in light and dark. */
.logo-tool-viewport.is-transparent {
  background-color: #ffffff;
  background-image: conic-gradient(#e0e0e0 25%, #ffffff 0 50%, #e0e0e0 0 75%, #ffffff 0);
  background-size: 24px 24px;
}

/* The frame IS the exported file: height and aspect-ratio set inline (padded dimensions
   when clear space is on), scaled down by the max rules when it does not fit. The script
   sets `color` here so the logo and the clear-space guides both inherit it.

   THE DEFINITE AXIS MUST BE HEIGHT. This used to set an explicit `width`, and that only
   ever fitted the width axis: with a definite width, max-height truncated this box
   without re-deriving through aspect-ratio, and the artwork inside did not shrink with
   it — the holder is sized off width — so the overflow was clipped by the stage. Every
   variation taller than it is wide lost its ends: both rotated secondaries at every
   width including 400px, and the square avatar once the stage was wider than tall.
   Measured in Chromium, container 600×300, artwork 555/1050:
     width:1057px + max-width + max-height -> 600×300  (ratio broken, clipped)
     height:2000px + max-width only        -> 600×2000 (overflows, no vertical cap)
     height:2000px + max-width + max-height -> 159×300 (correct on both axes)
   Both max rules are load-bearing; dropping either brings back one of the first two. */
.logo-tool-frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  max-height: 100%;
}

/* The holder is the LOGO box inside the file. Clear space is pure percentages — the
   script sets width:<logo/file %> so everything scales together with no padding drift. */
.logo-tool-holder {
  width: 100%;
}

.logo-tool-holder svg {
  display: block;
}

/* Clear-space guides — the exclusion zone made visible, as two dashed boxes like the
   brand diagram: the outer file edge (::before) and the inner logo box (::after, inset
   by the rendered pad). --clear-pad-px comes from the script and is kept correct in the
   same pass as the scale note. currentColor is the logo colour.

   opacity 0.7, not 0.4: the guides are the entire visual payload of the Clear space
   toggle, so they have to clear 3:1 non-text contrast (WCAG 1.4.11) against every
   background in the manifest. At 0.4 the off-black logo on white measured 2.46:1 and
   blue on white 1.92:1; at 0.7 the worst case is 3.47:1. */
.logo-tool-frame.is-clearspace::before,
.logo-tool-frame.is-clearspace::after {
  content: "";
  position: absolute;
  border: 1px dashed currentColor;
  opacity: 0.7;
  pointer-events: none;
}

.logo-tool-frame.is-clearspace::before {
  inset: 0;
}

.logo-tool-frame.is-clearspace::after {
  inset: var(--clear-pad-px, 0px);
}

/* -- Canvas footer --
   One bar under the canvas instead of five pills floating over it. The top border is
   the canvas edge: these readouts used to sit absolutely inside the stage, so nothing
   showed where the canvas stopped and a tall logo could run underneath them.

   flex: 0 0 auto against the stage's flex: 1 1 auto — the canvas is what gives, so the
   bar never gets squeezed and the preview re-fits around it on its own. Wraps rather
   than truncates: the filename is long by design and is the one thing here people copy.

   Two rows: the filename centred over a full-width status row. No justify-content here —
   the status row is width: 100% so it always claims its own line, and the filename's auto
   margins centre it, which beats any justify-content value the container could set. */
.logo-tool-footer {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-l);
  padding: var(--space-s) var(--space-2xl);
  /* --border-primary, not --border-faded: this line IS the canvas edge, so it carries
     information and has to be seen. Faded measured 1.41:1 against the surfaces either
     side; secondary only reached 2.52 light and 1.45 dark. Primary is the one colour
     that works, because the footer's own background is the only fixed reference — the
     canvas above it is whatever background the selected logo colour brings, so a rule
     tuned to the canvas disappears the moment someone picks the opposite colourway. */
  border-top: var(--border-s) solid var(--border-primary);
  background-color: var(--background-primary);
}

.logo-tool-footer-status {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  gap: var(--space-2xs) var(--space-l);
}

.logo-tool-contrast,
.logo-tool-scale-note,
.logo-tool-filename,
.logo-tool-size-note,
.logo-tool-error {
  margin: 0;
  font-size: var(--font-xs);
  overflow-wrap: anywhere;
}

.logo-tool-contrast,
.logo-tool-scale-note,
.logo-tool-size-note {
  color: var(--text-secondary);
}

/* The filename is selectable — people paste it into tickets and briefs. Centred over the
   status row: auto margins for the box, text-align for the lines inside it when it wraps. */
.logo-tool-filename {
  margin: 0 auto;
  color: var(--text-primary);
  font-family: var(--font-quaternary);
  text-align: center;
  user-select: all;
}

/* Colour, not an inverted pill: a pill was right when these floated over the canvas and
   a failure had to out-shout four other pills. In a bar the danger colour is enough, and
   an inverted block in a row of plain text reads as a badge rather than a problem. */
.logo-tool-error {
  color: var(--status-danger);
}

/* Not live regions — safe to remove from the tree entirely when empty. */
.logo-tool-contrast:empty,
.logo-tool-scale-note:empty,
.logo-tool-filename:empty {
  display: none;
}

/*
  The two live regions collapse WITHOUT display:none. A region that is absent from the
  accessibility tree at the moment its text is written does not announce, and unhiding
  it afterwards is not a content change — so `display: none` on an empty status or alert
  silently disables it. Clipping keeps it in the tree; the rule drops the instant text
  arrives and :empty stops matching.

  Out of flow, not merely zero-sized. `gap` applies between every adjacent pair of flex
  items whatever their size, so two collapsed regions at zero width still spent 2 ×
  --space-l and pushed the visible status text 32px clear of the footer's own padding
  edge — an offset that moved as notes came and went. An absolutely positioned flex item
  leaves the flex formatting context and takes its gaps with it. Same declarations as
  .visually-hidden (design-system.css section 10), for the same reason it uses them.

  One trap: :empty also matches a whitespace-only element, so a region written with ' '
  would mutate and stay hidden — the exact silent failure this rule exists to avoid.
  logo-tool.js writes `message || ''` in both places; keep it that way.
*/
.logo-tool-size-note:empty,
.logo-tool-error:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* -- Empty state -- */
.logo-tool-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-m);
  flex: 1 1 auto;
  padding: var(--space-2xl);
  text-align: center;
}

.logo-tool-empty[hidden] {
  display: none;
}

.logo-tool-empty .svg-icn {
  width: 2.5rem;
  height: 2.5rem;
  color: var(--text-faded);
}

.logo-tool-empty p {
  max-width: 42ch;
  margin: 0;
  color: var(--text-secondary);
}

/* -- Notes under gated controls -- */
.logo-tool-note {
  margin: 0;
  max-width: 22ch;
  color: var(--text-faded);
  font-size: var(--font-xs);
}

.logo-tool-note:empty,
.logo-tool-note[hidden] {
  display: none;
}

/* -- Mobile -- */
/*
  The .bar component already drops the group labels, tightens the gap and clamps the
  menu width at this breakpoint, so all that is left here is giving the variation select
  its own full-width line.
*/
@media (max-width: 768px) {
  .logo-tool-variant-group {
    flex: 1 0 100%;
  }

  .logo-tool-variant-group select {
    flex: 1 1 auto;
    min-width: 0;
  }

  .logo-tool-viewport {
    padding: var(--space-2xl) var(--space-l);
  }

  /* Matches the viewport's own narrowed inline padding, so the filename lines up with
     the canvas edge rather than sitting inside it. */
  .logo-tool-footer {
    padding: var(--space-s) var(--space-l);
  }
}

/* No prefers-reduced-motion block: this file declares no transitions or animations of
   its own. Everything that moves here (dropdown chevrons, button hovers) is the design
   system's, and carries its own guards. */
