/* =============================================================================
   cst-utilities.css

   Section-agnostic utility classes, linked by all three chrome templates:
   templates/header.cfm, templates/admin_header.cfm and
   includes/header/company_header.cfm.

   WHY THIS FILE EXISTS

     Phase 5 of docs/redesign-implementation-directive.md replaces inline style
     attributes with utility classes. Most of what the pages needed — spacing,
     text alignment, flex, display — Bootstrap and Tabler already provide. A
     small set they do not, and those gaps are what forced the inline styles in
     the first place: Bootstrap has no cursor utility, no letter-spacing
     utility, and only four width steps.

     Those gaps are the same in admin, company and public, so filling them once
     here beats three copies drifting apart. Section-specific styling stays
     where it was — admin chrome in templates/stylesheets/admin_styles.css,
     public in assets/css/cst-header.css and cst-public.css.

   WHAT DOES NOT BELONG HERE

     Colour. Every colour in the application comes from the token layer in
     templates/_project_css_vars.cfm, driven by ProjectDataValues. Nothing in
     this file should name a colour; if a rule needs one it belongs in a
     section stylesheet reading var(--token).
   ============================================================================= */


/* -----------------------------------------------------------------------------
   Width

   Two sets, deliberately distinguishable at a glance: .w-5 is 5 percent,
   .w-5r is 5 rem.

   PERCENTAGES fill the gaps in Bootstrap's set, which ships 25 / 50 / 75 / 100
   only. Those four are left alone so Bootstrap's own definitions still win.

   THE REM SCALE replaces fixed pixel widths. Before Phase 5 the admin alone
   carried 228 width declarations using 45 distinct values — 131 of them column
   widths on <th>, 46 on narrow inputs. That is not a scale, it is 45 arbitrary
   numbers.

   The fourteen steps below were picked to fit the values actually in use rather
   than off a generic scale, so the common ones land exactly: 80px (35 uses),
   160px, 240px and 400px are all exact, and nothing moved by more than 8px.
   ----------------------------------------------------------------------------- */

/* percentage — the steps Bootstrap leaves out */
.w-5  { width: 5%; }
.w-10 { width: 10%; }
.w-15 { width: 15%; }
.w-20 { width: 20%; }
.w-30 { width: 30%; }
.w-40 { width: 40%; }
.w-60 { width: 60%; }
.w-80 { width: 80%; }

/* fixed — the rem scale */
.w-3r  { width: 3rem; }    /*  48px */
.w-4r  { width: 4rem; }    /*  64px */
.w-5r  { width: 5rem; }    /*  80px */
.w-6r  { width: 6rem; }    /*  96px */
.w-7r  { width: 7rem; }    /* 112px */
.w-8r  { width: 8rem; }    /* 128px */
.w-9r  { width: 9rem; }    /* 144px */
.w-10r { width: 10rem; }   /* 160px */
.w-11r { width: 11rem; }   /* 176px */
.w-12r { width: 12rem; }   /* 192px */
.w-14r { width: 14rem; }   /* 224px */
.w-15r { width: 15rem; }   /* 240px */
.w-19r { width: 19rem; }   /* 304px */
.w-25r { width: 25rem; }   /* 400px */

/* Constrained preview image (a course/logo thumbnail). Caps the width and lets
   the height follow, so the aspect ratio is kept — unlike a plain width, which
   would upscale a small source. Pairs with Bootstrap's .img-thumbnail frame. */
.cst-thumb { max-width: 10rem; height: auto; }   /* 160px, capped by width  */
.cst-thumb--h { max-height: 10rem; width: auto; max-width: 100%; }  /* capped by height */

/* A flex child will not shrink below its content's intrinsic width unless its
   min-width is 0. Bootstrap ships no min-width utility, so text that must
   truncate/wrap inside a flex row carried min-width:0 inline. */
.min-w-0 { min-width: 0; }

/* Max-width caps (rem scale, matching the width utilities above). Used to bound
   a truncating cell or a narrow table so it does not stretch full width. */
.mw-19r { max-width: 19rem; }   /* ~304px */
.mw-31r { max-width: 31rem; }   /* ~496px */

.w-90 { width: 90%; }

/* Drag affordance for sortable list items (Bootstrap has no cursor-move). */
.cursor-move { cursor: move; }


/* -----------------------------------------------------------------------------
   Cursor

   Bootstrap ships no cursor utility, so every clickable non-button carried
   cursor:pointer inline. .cursor-pointer is the plain one; .expander below is
   the named case for a show/hide toggle.
   ----------------------------------------------------------------------------- */
.cursor-pointer { cursor: pointer; }


/* -----------------------------------------------------------------------------
   Expand / collapse affordance

   A plain line of text used as a show/hide toggle, driven by jQuery
   .show()/.hide(). Each call site used to repeat the same cursor, weight and
   size inline.

   .expander is the click target; .expander-title is the heading treatment,
   separate because some headings want the size and weight without being
   clickable. Neither maps to an existing utility — 1.125rem falls between
   Bootstrap's .fs-4 and .fs-5.
   ----------------------------------------------------------------------------- */
.expander { cursor: pointer; }

.expander-title {
    font-size: 1.125rem;
    font-weight: 600;
}


/* -----------------------------------------------------------------------------
   Letter spacing

   Small uppercase labels ("PRODUCT", "COURSE") pair text-uppercase with a half
   pixel of tracking. Bootstrap has no letter-spacing utility.
   ----------------------------------------------------------------------------- */
.tracking-wide { letter-spacing: .5px; }


/* -----------------------------------------------------------------------------
   Icon glyph sizes

   Our icons are webfont glyphs — <i class="ti ti-user"> from
   @tabler/icons-webfont — so they are sized by font-size.

   Tabler's own .icon-sm / .icon-md / .icon-lg cannot be used for them: those
   set --tblr-icon-size, which drives the width and height of an inline SVG and
   does nothing to a glyph. Hence a separate namespace rather than an override,
   so the two systems cannot be confused for each other.

   Sizes come from what the pages already used: 1.4rem for the readiness
   checklist ticks, 2.5rem and 3rem for the icon in an empty state or a status
   panel.
   ----------------------------------------------------------------------------- */
.glyph-md { font-size: 1.4rem; }
.glyph-lg { font-size: 2.5rem; }
.glyph-xl { font-size: 3rem; }


/* -----------------------------------------------------------------------------
   Stat tiles

   The KPI figure in a dashboard tile — seats used, courses completed, percent
   done. Four sizes, from the supporting figures beside a tile up to the single
   headline number on a dashboard.

   Kept as classes rather than three utilities each because the size, the tight
   line-height and the weight always travel together, and because the pairing
   is a component decision: if the stat treatment changes, it changes here
   instead of in twenty-odd places.

   .stat-value is 1.5rem, which is also Tabler's .fs-1, but naming it for the
   role keeps the tiles from drifting apart the next time the heading scale is
   adjusted.
   ----------------------------------------------------------------------------- */
.stat-value,
.stat-value-lg,
.stat-value-xl,
.stat-value-2xl {
    line-height: 1;
    font-weight: 600;
}

.stat-value     { font-size: 1.5rem; }
.stat-value-lg  { font-size: 1.75rem; }
.stat-value-xl  { font-size: 2rem; }
.stat-value-2xl { font-size: 2.5rem; }


/* -----------------------------------------------------------------------------
   Donut chart with a centred figure

   A hand-rolled SVG donut on the company dashboards — seats used, learner
   progress, percent complete — with the headline number stacked in the middle
   of the ring.

   Two parts that only work as a pair: the wrapper establishes the positioning
   context, the label centres against it. They were four copies each of the
   same two style attributes, and getting one of them wrong silently drops the
   figure into the corner of the card.
   ----------------------------------------------------------------------------- */
.donut {
    position: relative;
    display: inline-block;
}

.donut-label {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
}
