/*
 * Lux Neon USA — "My logo in neon"  (customizer v3)
 * -------------------------------------------------
 * Copied from public/neon-customizer.css and cut down. Mobile first: every
 * rule below is the phone layout and the media queries at the bottom widen it.
 *
 * The root class is `.neon-logo`, not `.neon-customizer`. Both files define a
 * block of custom properties on their root and both use the shared `nc-`
 * element namespace, so on any page that ever carried BOTH widgets — a Shopify
 * template offering "text or logo" is the obvious one — a shared root class
 * would let whichever stylesheet loaded second silently retune the other. The
 * `nc-` element rules are identical in both files and can safely collide; the
 * root cannot.
 *
 * WHAT IS GONE FROM v1's SHEET
 *   - The @import of the five chip typefaces. There is no font row here, so it
 *     would be five display faces fetched for nothing.
 *   - .nc-input and .nc-row--fonts / .nc-row--sizes. No textarea, no font
 *     chips, no size chips — see the header of public/neon-logo.js for why.
 * WHAT IS NEW
 *   - .nc-drop, the upload target.
 *   - .nc-row--styles, labelled chips instead of bare glyphs.
 * AND GONE AGAIN
 *   - the colour dots, removed 2026-09-04. The sign always keeps the logo's own
 *     colours, so there was nothing left to choose.
 */

.neon-logo {
  --nc-bg: #0d0f14;
  --nc-panel: #14171f;
  --nc-panel-hi: #1c212c;
  --nc-line: #262c38;
  --nc-line-strong: #46506a;
  --nc-text: #f2f4f8;
  --nc-muted: #98a1b4;
  --nc-accent: #25d366; /* WhatsApp green — the one branded colour here */
  --nc-radius: 14px;

  /* The single vertical rhythm value. Every gap between the viewport, the
   * upload box and the two chip rows is one of these, so the whole layout
   * tightens or loosens from here. */
  --nc-gap: 10px;

  display: block;
  box-sizing: border-box;
  max-width: 720px;
  margin: 0 auto;
  padding: 0;
  color: var(--nc-text);
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

.neon-logo *,
.neon-logo *::before,
.neon-logo *::after {
  box-sizing: inherit;
}

/* ------------------------------------------------------------- viewport */

/* 3:2, the widest of the three canvases the endpoint can return. See
 * .nc-shot__img below for why the frame's ratio matters much less here than it
 * did in v1. */
.nc-view {
  position: relative;
  aspect-ratio: 3 / 2;
  border-radius: var(--nc-radius);
  border: 1px solid var(--nc-line);
  background: radial-gradient(120% 90% at 50% 40%, #171b24 0%, var(--nc-bg) 70%);
  overflow: hidden;
}

/* Fallback for browsers without aspect-ratio (Safari < 15). */
@supports not (aspect-ratio: 1) {
  .nc-view { height: 61vw; max-height: 380px; }
}

/* The execute control, centred in the frame. A real bordered button rather
 * than a transparent full-bleed one: in v1 the full-bleed version read as
 * placeholder copy rather than a control, which is the one thing it cannot
 * afford to do — it is the only action that produces the picture. */
.nc-idle {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 20px;
  text-align: center;
  pointer-events: none; /* only the button itself is clickable */
}

.nc-run {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid var(--nc-line-strong);
  border-radius: 999px;
  background: rgba(28, 33, 44, 0.92);
  color: var(--nc-text);
  font-family: inherit;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
}

.nc-run:hover:not(:disabled) {
  background: #232936;
  border-color: #5d6885;
}

.nc-run:active:not(:disabled) { transform: scale(0.98); }

.nc-run:focus-visible {
  outline: 2px solid var(--nc-text);
  outline-offset: 3px;
}

.nc-run:disabled {
  cursor: default;
  opacity: 0.5;
  box-shadow: none;
}

/* A triangle rather than a sparkle: this is the one control that executes
 * something, and it should look like it. */
.nc-run__icon {
  font-size: 12px;
  line-height: 1;
  color: var(--nc-muted);
}

.nc-run:hover:not(:disabled) .nc-run__icon { color: var(--nc-text); }

.nc-hint {
  margin: 0;
  max-width: 28ch;
  font-size: 13px;
  line-height: 1.35;
  color: var(--nc-muted);
}

/* Once an image exists the control stops covering it: it drops to a pill in
 * the corner so the render owns the frame. */
.nc-view.has-shot .nc-idle {
  inset: auto 10px 10px auto;
  padding: 0;
  align-items: flex-end;
}

.nc-view.has-shot .nc-run {
  min-height: 42px;
  padding: 0 16px;
  font-size: 14px;
  background: rgba(10, 12, 17, 0.86);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* The render failure message. Sits above the run button in the same flex
 * column, so the two stack instead of overlapping — see the note in the
 * widget's build(). Kept narrow and centred like .nc-hint, but at full
 * contrast: this one is the reason the frame is empty, not a footnote. */
.nc-err {
  margin: 0;
  max-width: 34ch;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(10, 12, 17, 0.86);
  border: 1px solid var(--nc-line-strong);
  /* Kept from the rule this replaced: a failure should read as a problem,
     not as another hint. */
  color: #ffb4b4;
  font-size: 13.5px;
  line-height: 1.4;
}

.nc-view.has-shot .nc-hint { display: none; }

/* The picture on screen already IS the current design, so the run button has
 * nothing left to do — it is hidden and the reason beside it becomes the whole
 * message. Only applies once there is a render to be current WITH; every other
 * disabled state keeps the button, because it is what will work again. */
.nc-view.has-shot .nc-idle.is-current .nc-run { display: none; }


/* …except when the button is disabled, where the hint IS the explanation. */
.nc-view.has-shot .nc-idle.is-blocked .nc-hint {
  display: block;
  max-width: 22ch;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(10, 12, 17, 0.86);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 11.5px;
  text-align: right;
}

.nc-shot {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* `contain`, where v1 uses `cover` — the one substantive styling difference
 * between the two widgets, and it is not a taste call.
 *
 * v1 always renders a wide sign into a wide frame, so cover crops a sliver of
 * background and nothing else. v3's canvas follows the shape of the upload
 * (square badge, wide wordmark, tall lockup — see canvasFor in the endpoint),
 * so a square render inside a 3:2 frame under `cover` loses a third of its
 * width. On a logo that is fatal: the crop takes the mark itself, and the
 * customer is looking at the picture precisely to check their mark survived.
 *
 * The cost is letterboxing. The frame's background is the same near-black the
 * render's wall is, so the bars read as more wall rather than as a gap. */
.nc-shot__img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

/* Stale: the picture is from a design the customer has since changed. Dimmed
 * and desaturated so it plainly reads as "not current", with a badge naming
 * the reason — a silent stale image makes the controls look broken. */
.nc-view.is-stale .nc-shot__img {
  filter: saturate(0.45) brightness(0.5);
  transition: filter 0.2s ease;
}

.nc-view.is-stale::before {
  content: 'Preview of an earlier design';
  position: absolute;
  z-index: 1;
  top: 10px;
  left: 10px;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(10, 12, 17, 0.86);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--nc-line);
  font-size: 11.5px;
  color: var(--nc-text);
}

/* Loading: a slow sweep across the empty viewport. No percentage and no timer
 * — the wait is 20-40s and a stalled bar reads as broken. */
.nc-view.is-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 20%,
    rgba(255, 255, 255, 0.07) 50%,
    transparent 80%
  );
  background-size: 220% 100%;
  animation: nc-sweep 1.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes nc-sweep {
  from { background-position: 180% 0; }
  to { background-position: -80% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .nc-view.is-loading::after { animation: none; }
}

/* ------------------------------------------------------------- controls */

.nc-panel { padding: var(--nc-gap) 0 0; }

/* ---- the upload target ----
 *
 * A <label> wrapping a visually-hidden file input, which is why the whole box
 * is clickable and keyboard reachable without a line of JavaScript. It is also
 * a drop target and the widget accepts a paste — three ways in, because on a
 * phone it is the camera roll, on a desktop it is a drag, and for the owner
 * testing marks it is Cmd+V straight out of a design tool. */
.nc-drop {
  /* The containing block for the clipped file input below, which is absolutely
   * positioned — without this it would anchor to the page and its 1px box would
   * sit wherever the last positioned ancestor happens to be, dragging focus
   * scroll with it. */
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 10px 14px;
  border: 1px dashed var(--nc-line-strong);
  border-radius: var(--nc-radius);
  background: var(--nc-panel);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.nc-drop:hover,
.nc-drop.is-over {
  border-color: var(--nc-text);
  background: var(--nc-panel-hi);
}

/* Once a logo is in, the box has a subject and stops advertising itself. */
.nc-drop.has-logo {
  border-style: solid;
  border-color: var(--nc-line);
}

/* Clipped rather than `display: none`: a hidden input is skipped by the
 * keyboard and by some screen readers, and the label would then have nothing
 * to activate. */
.nc-file {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The focus ring belongs on the box, not on the 1px input inside it: the input
 * is what takes focus, but the label is what the customer sees. `:focus-within`
 * is the only selector that can move it there. */
.nc-drop:focus-within {
  outline: 2px solid var(--nc-line-strong);
  outline-offset: 2px;
}

/* The customer's own artwork, shown back to them.
 *
 * `contain` and a light ground: this is the flattened PNG that will actually be
 * posted, so a white-on-transparent wordmark has already been composited onto
 * near-black by then and shows correctly. Seeing the prepared image rather than
 * the raw file is the point — if the flattening picked the wrong ground, the
 * thumbnail is where that becomes visible before a render is spent on it. */
.nc-drop__thumb {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 10px;
  border: 1px solid var(--nc-line);
  background-color: #0a0b0f;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

.nc-drop__text {
  min-width: 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--nc-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Error line. Empty and fully collapsed the rest of the time — `:empty`
 * removes the box entirely rather than reserving a blank strip. */
.nc-note {
  margin: var(--nc-gap) 2px 0;
  font-size: 12.5px;
  line-height: 1.35;
  color: #ffb4b4;
  overflow-wrap: anywhere;
}

.nc-note:empty { display: none; }

.nc-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: var(--nc-gap);
}

/* ---- style chips ---- */

.nc-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--nc-line);
  border-radius: var(--nc-radius);
  background: var(--nc-panel);
  color: var(--nc-text);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  /* 44px is the accessibility floor for a touch target; 48 leaves the 4px of
   * headroom that absorbs the chip's own border. */
  min-height: 48px;
}

.nc-chip:focus-visible {
  outline: 2px solid var(--nc-line-strong);
  outline-offset: 2px;
}

.nc-chip.is-selected {
  border-color: var(--nc-line-strong);
  background: var(--nc-panel-hi);
}

/* Three across even on a small phone. These carry a word and a sub-line rather
 * than v1's bare `Aa`, because "Simplificado" versus "Fiel" is not something a
 * glyph can show — and picking wrong costs a render. */
.nc-row--styles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.nc-row--styles .nc-chip {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  padding: 8px 10px;
  text-align: left;
}

.nc-chip__name {
  font-size: 14px;
  font-weight: 600;
}

/* Wraps, unlike v1's price line. The sub-line is a sentence rather than a
 * figure, and a truncated explanation is worse than a two-line chip. */
.nc-chip__note {
  font-size: 10.5px;
  line-height: 1.25;
  color: var(--nc-muted);
}

/* ---- size chips ---- */

/* Five across on a phone. Each holds one short inch figure (the DR twin
 * carried centimetres, and for a while both), so they fit where the three style chips would not — and a size
 * row that wraps to two lines would push the price bar off a small screen. */
.nc-row--sizes {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
}

.nc-row--sizes .nc-chip {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 8px 4px;
}

/* The inch figure is the whole chip — in the USA build it is the unit the
 * customer buys in AND the one the card prices in, so there is no second line
 * to carry (see the note in neon-logo.js). Matches .nc-chip__size in
 * neon-customizer.css so the two customizers' size chips read alike. */
.nc-chip__size {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.1;
  white-space: nowrap;
}

/* What the price covers. Small, quiet, and always present — it is not a
 * disclaimer to be discovered, it is part of what the number means. */
.nc-terms {
  margin: 8px 2px 0;
  font-size: 11px;
  line-height: 1.35;
  color: var(--nc-muted);
}

/* No colour dots. The swatch row was removed on 2026-09-04 — the sign always
 * keeps the logo's own colours, so there is nothing to choose. The rules that
 * drew twelve dots and the conic-gradient "all colours" swatch went with it;
 * git history has them if a single "otro color" control is ever wanted, which
 * is the shape to bring back rather than the row. */

/* ------------------------------------------------------------------ bar */

.nc-bar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: var(--nc-gap);
  padding: 10px 14px;
  /* Clears the iPhone home indicator. */
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  border: 1px solid var(--nc-line);
  border-radius: var(--nc-radius);
  background: rgba(15, 18, 24, 0.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.nc-price {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.nc-price__label {
  font-size: 10.5px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--nc-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nc-price__value {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.nc-wa {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 18px;
  border-radius: 999px;
  background: var(--nc-accent);
  color: #04210f;
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.nc-wa:hover { filter: brightness(1.06); }
.nc-wa:focus-visible { outline: 2px solid var(--nc-text); outline-offset: 2px; }

/* Inert until there is a design to send. The `href` is removed in JS, so this
 * is only the appearance of that state — but `pointer-events: none` is not
 * decoration either: without it the hover brightening below still fires and
 * the button reads as clickable while doing nothing, which is worse than
 * either state on its own. */
.nc-wa.is-disabled {
  opacity: 0.4;
  cursor: default;
  pointer-events: none;
}

/* ------------------------------------------------------------- >= 600px */

@media screen and (min-width: 600px) {
  .neon-logo {
    /* Desk and tablet have the height to spare, so the layout loosens back up
     * once the one-screen-on-a-phone constraint stops applying. */
    --nc-gap: 14px;
  }

  .nc-run { font-size: 18px; min-height: 54px; padding: 0 28px; }
  .nc-hint { font-size: 13.5px; }

  .nc-drop { min-height: 76px; }
  .nc-drop__thumb { width: 58px; height: 58px; }
  .nc-drop__text { font-size: 15.5px; }

  .nc-chip__name { font-size: 15px; }
  .nc-chip__note { font-size: 11.5px; }

  .nc-price__value { font-size: 22px; }
  .nc-chip__size { font-size: 16px; }
}

@supports not (aspect-ratio: 1) {
  @media screen and (min-width: 600px) {
    .nc-view { height: 400px; max-height: none; }
  }
}

/* ------------------------------------------------------------- >= 900px */

@media screen and (min-width: 900px) {
  /* The bar stops sticking once the whole widget fits on one screen — a
   * floating bar over a fully visible layout is just clutter. */
  .nc-bar { position: static; }
}

/* --------------------------------------------------------- light theme */

/* The widget stays dark in a light theme rather than inverting: a neon sign
 * only reads as lit against a dark field, and every reference photograph is a
 * dark wall. The border is lifted so the panel does not float untethered on a
 * white page. */
@media (prefers-color-scheme: light) {
  .neon-logo { --nc-line: #2f3644; }
}

/* ------------------------------------------------------------ >= 1024px */

/* TWO COLUMNS: the picture beside the controls (owner, 2026-09-22).
 *
 * The twin of the block at the end of neon-customizer.css, and written out
 * again rather than shared — ADR-002. The two widgets have no common code and
 * this one's panel is a different shape: an upload box, three labelled style
 * chips and five size chips, where v1 has a textarea and three bare chip rows.
 * A change here is not a change there. Check the twin.
 *
 * Below this the widget is one column capped at 720px, which is right on a
 * phone and wasteful on a desktop — the render, the thing the customer is here
 * to look at, was drawn at 720px on a 1920px screen with empty gutters either
 * side of it.
 *
 * The control column scales, `clamp(340px, 30vw, 420px)`, for the reason set
 * out in the twin: a fixed column starves the picture at the narrow end, and
 * the picture ends up shorter than the controls it is meant to lead. It is a
 * variable because the same number appears in the grid track AND in the
 * picture's width limit, and those two must never drift apart.
 */
@media screen and (min-width: 1024px) {
  .neon-logo {
    --nc-panel-w: clamp(340px, 30vw, 420px);

    /* A ceiling, not a width. The picture is sized from the viewport and the
       grid is content-sized, so the widget is as wide as the picture makes it;
       this only stops it running away on an ultrawide. */
    max-width: min(1760px, 100%);
    display: grid;

    /* `auto`, not a fraction. The frame has a definite height and a fixed
       ratio, so its width is already decided; an `auto` track takes exactly
       that. A fractional track would stretch the frame to the available width
       and force its height to follow, which pins the picture to one size on
       every screen regardless of how much room there is. */
    grid-template-columns: auto var(--nc-panel-w);

    /* The picture spans both rows; the controls sit at the top of the right
       column and the price bar is pinned to the foot of it, level with the
       base of the picture. Options at the top, the commercial decision at the
       bottom — and the column fills instead of trailing off into space. */
    grid-template-areas:
      'view panel'
      'view bar';
    grid-template-rows: auto 1fr;
    column-gap: 28px;
    justify-content: center;
    align-items: start;
  }

  .nc-view {
    grid-area: view;

    /* Sized from the viewport, under TWO limits, whichever is tighter:
     *
     *   - `100vh - 300px` is the chrome above and below. Larger than the
     *     twin's 260px because this page carries a subtitle under its <h1>
     *     that /customizer/ does not.
     *   - the second term is the WIDTH limit solved back into a height: the
     *     picture can be at most (available - column - 28px) wide, and at 3:2
     *     that is a height a third less again. 64px covers the page's 16px
     *     gutters plus a scrollbar, which `100vw` counts and we do not get.
     *
     * Without the second term the picture overflows sideways on any screen
     * wider than it is tall, which is most of them. */
    height: clamp(
      320px,
      min(
        calc(100vh - 300px),
        calc((min(100vw - 64px, 1760px) - var(--nc-panel-w) - 28px) / 1.5)
      ),
      820px
    );
    width: auto;

    /* Without this the grid item stretches to its track and the track sizes to
       the item — circular, and the browser resolves it by ignoring the height. */
    justify-self: start;
  }

  .nc-panel {
    grid-area: panel;
    /* Nothing above it to clear once it is beside the picture rather than
       under it; the gap would just drop the controls out of line. */
    padding-top: 0;
  }

  .nc-bar {
    grid-area: bar;
    align-self: end;
    margin-top: var(--nc-gap);
  }

  /* Five size chips across a 340px column leaves ~63px each, which is too
     narrow to read comfortably at the desktop type size. Three across wraps to
     two rows in a column that has height to spare, and keeps every chip wide
     enough to read. */
  .nc-row--sizes { grid-template-columns: repeat(3, 1fr); }
}

/* ------------------------------------------------------------ >= 1280px */

/* The controls grow once the column does — and only if there is height for it.
 *
 * The height condition is not decoration. Enlarged, the control column can
 * stand taller than the picture beside it, and then the COLUMN sets the
 * widget's height; on a 1366x768 laptop that is the difference between fitting
 * exactly and a full-height scrollbar for a few pixels. Shrinking the picture
 * does not help, because the picture was never the tall one.
 *
 * Worth doing on its own merits and not only to fill space: this is a mouse on
 * a large screen, and every one of these was sized for a thumb on a phone. */
@media screen and (min-width: 1280px) and (min-height: 820px) {
  .neon-logo { --nc-gap: 18px; }
  .nc-drop { min-height: 92px; }
  .nc-drop__thumb { width: 66px; height: 66px; }
  .nc-row--styles .nc-chip { padding-top: 12px; padding-bottom: 12px; }
  .nc-row--sizes .nc-chip { padding-top: 12px; padding-bottom: 12px; }
}
