/* ============================================================
   UI TEMPLATES — the look of the shared interface pieces
   ============================================================
   Pairs with js/ui-templates.js: that file builds the markup,
   this one dresses it. Prefix .cl- (cabinet label) so nothing
   collides with the per-screen classes already in
   panel-links.css / modals.css.

   Anatomy of a cabinet label — one line tall, everything
   vertically centred on the name:

       [icon] SERVER-04  B,01
                         Zone name

   The whole thing scales from ONE number: the font-size on
   .cl is the size of the cabinet name, and every other piece
   is expressed in em of it. Set .cl { font-size: 18px } and
   icon, coordinate and zone follow on their own.

   The tags UITpl prints are .badge now (css/ui-primitives.css);
   what is left here is the fibre tones below, because the colour
   of a fibre tag means a kind of cable and not a state of the
   interface. The panel-side badge (.lp-ep-panel-badge) keeps its
   own class for the same reason: blue is the front, red the rear.
   ============================================================ */

:root {
    /* Cabinet names are shown in capitals. Set to `none` to see them as typed. */
    --cl-name-transform: uppercase;
    /* Coordinate and zone, as a share of the cabinet-name size. */
    --cl-meta-scale: 0.4;
    /* ...but never smaller than this. At 0.4 the pair stops being readable
       below a ~22px name, and most of the app labels cabinets at 13-16px.
       Set to 0 to get the pure proportion at every size. */
    --cl-meta-min: 9px;
}

.cl {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    /* Never wider than what holds it: in a table cell or a card the name has to give
       way and clip, not push the coordinate and the zone out of sight. */
    max-width: 100%;
    min-width: 0;
    vertical-align: middle;
    line-height: 1;
}

/* Exactly as tall as the name next to it. The icons are square (20x20 viewBox),
   so one number does both sides. */
.cl-icon {
    flex-shrink: 0;
    width: 1em;
    height: 1em;
    opacity: 0.85;
}

/* The cabinet name is the anchor: it sets the size everything else derives from,
   and it never wraps — in a card or a table cell a second line would push the
   rest out of view, so it clips instead. */
.cl-name {
    font-weight: 700;
    text-transform: var(--cl-name-transform, uppercase);
    letter-spacing: 0.01em;
    /* A flex item defaults to min-width:auto and refuses to shrink below its text;
       without this the ellipsis never appears and the name overflows the cell. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Coordinate over zone, in their own column right of the name. Two lines at 0.4em
   with line-height 1.15 come to ~0.92em — just under the name's own height, which
   is what keeps the whole label one line tall. */
.cl-meta {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-width: 0;
    /* When the room runs out the NAME gives way, not the coordinate — a clipped name
       is still recognisable, a clipped coordinate is worthless. The cap keeps a very
       long zone from eating the name instead. */
    flex-shrink: 0;
    max-width: 14em;
    font-size: max(var(--cl-meta-min), calc(1em * var(--cl-meta-scale)));
    line-height: 1.15;
    color: var(--dc-c-muted);
}

.cl-coord {
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.cl-zone {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* RESERVED takes the zone's place — see cabinetLabel() in js/ui-templates.js. */
.cl-flag {
    font-weight: 700;
    letter-spacing: 0.06em;
    color: #b0392b;
}

/* ── Sizes ────────────────────────────────────────────────────────────────────
   One declaration each: the name size, and the rest follows.
   sm — dense lists and report tables, md — cards and list rows,
   lg — modal titles and anything that has to be read across the room. */

/* ── Fibre tones for .badge ───────────────────────────────────────────────────
   The colours of the cable itself, not of the interface: single-mode is yellow,
   OM4 is magenta, copper is the amber of an RJ45 boot. They are here rather than
   among the primitive's own tones because they mean a kind of cable, and they are
   here rather than in productSelector.css because UITpl.fiberTag prints them and
   the product selector is only one of the places that shows one.

   Each sets the three properties the primitive paints from and paints nothing
   itself - see the .badge block in css/ui-primitives.css. Pair with --edged: on a
   card full of photographs a fill alone does not hold its edge. */

.badge--fiber-sm  { --badge-soft: #fdfbe0; --badge-ink: #6b6100; --badge-line: #ece343; }
.badge--fiber-om4 { --badge-soft: #fce8ef; --badge-ink: #8c3050; --badge-line: #df829d; }
.badge--fiber-om3 { --badge-soft: #e4f5f3; --badge-ink: #1f6b62; --badge-line: #9fd4cd; }
.badge--copper    { --badge-soft: #fef0e6; --badge-ink: #c0622a; --badge-line: #f0d2be; }

.cl--sm { font-size: var(--dc-text-sm); }
.cl--md { font-size: var(--dc-text-lg); }
.cl--lg { font-size: var(--dc-text-2xl); }

/* ── Module caption: UITpl.moduleCaption() ────────────────────────────────────
   "A1/A2   [icon] NETWORK  C,04 · PP-01 A3/A4" — the position a module stands in
   on this panel, then where its fibres come out at the far end.

   Three containers draw it and each styled both halves from scratch, so outside
   those three the slot sat flush against the icon with no gap at all. These two
   rules are the caption's own look, the way .cl-* above is the cabinet label's.

   What is NOT here, and cannot be: the layout of the whole. moduleCaption()
   returns two spans and no wrapper — the flex box around them belongs to whoever
   draws it, and the three do not agree about it on purpose. .panel-module-dest
   clips, .cabinet-label-overlay lets the label spill past its module because it
   floats above the drawing, and .odf-cassette-label is eight pixels rather than
   3.6 and separates the columns with the parent's own gap. So overflow, clipping
   and white-space stay with the container. A template can own the look of its
   parts; it cannot own a box it does not emit. */

/* Never squeezed: the slot is the shortest string in the caption and the first
   thing a flex row would take space from. 5ch keeps the column straight down a
   list of modules whether the slot reads A1 or A1/A2. */
.ml-slot {
    flex-shrink: 0;
    min-width: 5ch;
}

/* Air between the two columns. .odf-cassette-label sets this back to 0 - it
   separates them with gap on the row instead, and would otherwise get both. */
.ml-dest {
    padding-left: 3px;
}
