/* ============================================================
   Ikeja Electric: PrimeFaces theme bridge
   Maps the design tokens (ie-design-tokens.css) onto PrimeFaces'
   built-in .ui-* classes so p:* components follow the design
   system without rewriting their markup.

   USAGE (JSF app):
   1. Set the app to the "none" built-in theme so these rules win:
        <context-param>
          <param-name>primefaces.THEME</param-name>
          <param-value>none</param-value>
        </context-param>
   2. Load AFTER any PrimeFaces CSS, e.g. in your template <h:head>:
        <h:outputStylesheet library="css" name="ie-design-tokens.css"/>
        <h:outputStylesheet library="css" name="ie-primefaces.css"/>
   3. Put data-theme / data-brand on <body> (or <html>):
        <body data-theme="light" data-brand="amber"> ... </body>

   Adjust selectors to your PrimeFaces version if class names differ.
   Verified against the .ui-* class family used in PF 8:13.
   ============================================================ */

/* ---- Base / typography ---- */
body, .ui-widget, .ui-widget input, .ui-widget select,
.ui-widget textarea, .ui-widget button {
  font-family: var(--font-sans);
  color: var(--text);
}
.ui-widget-content { background: var(--surface); color: var(--text); border-color: var(--border); }
.ui-widget-header  { background: var(--surface-2); color: var(--text); border-color: var(--border); }
a { color: var(--primary); }
a:hover { color: var(--primary-hover); }

/* ---- Buttons (p:commandButton, p:button) ---- */
.ui-button,
.ui-button.ui-state-default {
  background: var(--primary);
  color: var(--on-primary);
  border: 1px solid var(--primary);
  border-radius: var(--radius-md);
  font-weight: 700;
  padding: .65em 1.1em;
  box-shadow: var(--shadow-xs);
  transition: background .15s ease;
}
.ui-button:hover,
.ui-button.ui-state-hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--on-primary); }
.ui-button:active,
.ui-button.ui-state-active { background: var(--primary-press); border-color: var(--primary-press); }
.ui-button:focus,
.ui-button.ui-state-focus { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.ui-button.ui-state-disabled,
.ui-button:disabled { opacity: .5; cursor: not-allowed; }

/* Secondary button: add styleClass="ie-secondary" */
.ui-button.ie-secondary {
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); box-shadow: none;
}
.ui-button.ie-secondary:hover { background: var(--surface-3); }
/* Ghost: styleClass="ie-ghost" */
.ui-button.ie-ghost { background: transparent; color: var(--primary); border-color: transparent; box-shadow: none; }
.ui-button.ie-ghost:hover { background: var(--primary-soft); }
/* Destructive: styleClass="ie-danger" */
.ui-button.ie-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.ui-button.ie-danger:hover { filter: brightness(.93); }
/* Compact button for dense rows (tables): styleClass="ie-btn-sm" */
.ui-button.ie-btn-sm { padding: .45em .8em; font-size: 12.5px; white-space: nowrap; }

/* Icon-only buttons - a p:commandButton given an icon and a title but no value.
   PrimeFaces still emits the accessible label in a .ui-button-text span and relies on
   the THEME to size the button and take that text out of flow. The theme is disabled
   here, so the label rendered as visible text: the Users & roles action column showed
   "Edit Set password Disable" spelled out beside each icon, blowing out the row.
   These rules size the button and hide the label without losing it for screen readers
   (the control keeps its title attribute). Placed AFTER .ie-btn-sm so the square size
   wins over that rule's padding at equal specificity. */
.ui-button.ui-button-icon-only {
  width: 32px; height: 32px; padding: 0; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
.ui-button.ui-button-icon-only.ie-btn-sm { width: 28px; height: 28px; padding: 0; }
/* A ghost icon button is a bare glyph on the row background - too little affordance to
   find in a dense table, which is what made the Users & roles actions hard to spot even
   once they fit. Give the icon-only variant a real (if quiet) chip so each one reads as
   a target. Text ghost buttons elsewhere keep their borderless look. */
.ui-button.ui-button-icon-only.ie-ghost {
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text-2);
}
.ui-button.ui-button-icon-only.ie-ghost:hover {
  background: var(--primary-soft); border-color: var(--primary); color: var(--primary);
}
.ui-button.ui-button-icon-only .ui-icon.pi { font-size: 13px; }
.ui-button.ui-button-icon-only .ui-button-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.ui-button.ui-button-icon-only .ui-button-icon-left {
  position: static; float: none; margin: 0; left: auto; top: auto;
  display: flex; align-items: center; justify-content: center; font-size: 13px;
}

/* ---- PrimeIcons inside a jQuery-UI .ui-icon slot -------------------------
   PrimeFaces renders an icon span as `class="ui-icon ui-c pi pi-pencil"`, and its own
   components.css - which JSF registers AFTER our stylesheets - says:

       .ui-icon { text-indent:-99999px; overflow:hidden; background-repeat:no-repeat }

   Those rules exist to show a sprite-sheet background and hide the element's text. A
   PrimeIcon is not a sprite: it is a font glyph drawn in ::before content. So the
   text-indent shoves the glyph 99999px to the left and overflow:hidden clips it - the
   icon is invisible and an icon-only button renders as a blank square. That was the
   Users & roles edit / set-password / disable column.

   PrimeFaces ships precisely this fix for Font Awesome (`.ui-icon.fa`) but not for
   PrimeIcons, because 6.2 predates bundling them. This is that missing counterpart, and
   it is deliberately global: every icon-only button in the app has the same problem.
   The paginator arrows below were an earlier one-off of the same bug. */
.ui-icon.pi {
  background: none !important;
  text-indent: 0 !important;
  overflow: visible;
  width: auto; height: auto;
  line-height: 1;
}

/* ---- Inputs (p:inputText, p:password, p:inputTextarea, h:inputText) ---- */
.ui-inputfield,
.ui-inputtext,
.ui-widget input.ui-inputtext,
.ui-widget textarea.ui-inputtextarea {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: .65em .8em;
  font-family: var(--font-sans);
}
.ui-inputtext:enabled:hover { border-color: var(--border-strong); }
.ui-inputtext:enabled:focus,
.ui-inputtext.ui-state-focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}
.ui-inputtext.ui-state-error,
.ui-inputfield.ui-state-error { border-color: var(--danger); border-width: 1.5px; }
::placeholder { color: var(--text-3); }

/* ---- Dropdown / select ---- */
.ui-selectonemenu, .ui-dropdown {
  background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--radius-md); color: var(--text);
}
.ui-selectonemenu.ui-state-focus, .ui-dropdown.ui-state-focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--ring); }
.ui-selectonemenu-panel, .ui-dropdown-panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.ui-selectonemenu-item.ui-state-highlight, .ui-dropdown-item.ui-state-highlight { background: var(--primary-soft); color: var(--text); }
/* The trigger's caret is a jQuery-UI sprite the "none" theme omits, so every dropdown
   in the app rendered with no arrow and read as a plain text box. */
.ui-selectonemenu .ui-selectonemenu-trigger, .ui-dropdown .ui-dropdown-trigger {
  background: none; border: none; color: var(--text-3);
  display: flex; align-items: center; justify-content: center;
}
.ui-selectonemenu .ui-selectonemenu-trigger .ui-icon,
.ui-dropdown .ui-dropdown-trigger .ui-icon {
  background-image: none !important; text-indent: 0 !important; overflow: visible;
  width: auto !important; height: auto !important; margin: 0;
  font-family: 'primeicons'; font-style: normal; font-weight: normal; line-height: 1;
}
.ui-selectonemenu .ui-selectonemenu-trigger .ui-icon:before,
.ui-dropdown .ui-dropdown-trigger .ui-icon:before { content: '\e902'; font-size: 12px; }

/* ---- Checkbox / radio ---- */
.ui-chkbox-box.ui-state-active, .ui-radiobutton-box.ui-state-active { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.ui-chkbox-box, .ui-radiobutton-box { background: var(--surface-2); border: 1.5px solid var(--border-strong); border-radius: var(--radius-sm); }
.ui-radiobutton-box { border-radius: var(--radius-full); }

/* ---- Panels & cards (p:panel, p:outputPanel, p:fieldset) ---- */
.ui-panel, .ui-fieldset, .ui-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
}
.ui-panel .ui-panel-titlebar,
.ui-fieldset .ui-fieldset-legend {
  background: var(--surface-2);
  color: var(--text);
  border: none;
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}

/* ---- DataTable (p:dataTable): clean, borderless list that blends into its card ----
   The tables live inside a .card, so the table itself carries NO outer chrome: no border,
   no grid lines, no background of its own. Just uppercase muted headers, a single hairline
   under the header, quiet row dividers and a soft hover band. !important is used throughout
   because PrimeFaces 6.2's core datatable CSS loads after this file and otherwise wins the
   ties (it is what draws the centred headers and vertical grid lines we are removing). */
.ui-datatable {
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  width: 100%;
}
.ui-datatable .ui-datatable-tablewrapper { overflow-x: auto; }
.ui-datatable table { border-collapse: collapse !important; width: 100% !important; }

/* header labels: small uppercase, muted, left-aligned, no vertical lines */
.ui-datatable thead th,
.ui-datatable .ui-datatable-thead > tr > th {
  background: transparent !important;
  color: var(--text-3) !important;
  border: 0 !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 12px 16px !important;
  text-align: left !important;
  white-space: nowrap;
}
/* a single hairline under the LAST header row (labels row, or the filter row when present),
   so filtered and unfiltered tables both get exactly one divider: never a double line */
.ui-datatable thead tr:last-of-type th { border-bottom: 1.5px solid var(--border) !important; }

/* per-column filter row: quiet, no boxy cell background */
.ui-datatable thead .ui-filter-column,
.ui-datatable tr.ui-filter-columns > th {
  background: transparent !important;
  border: 0 !important;
  padding: 0 12px 10px !important;
}
.ui-datatable thead tr.ui-filter-columns:last-of-type th { border-bottom: 1.5px solid var(--border) !important; }
.ui-datatable .ui-column-filter {
  width: 100%;
  box-sizing: border-box;
  font-size: 12.5px;
  font-weight: 400;
  padding: 7px 10px;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-sm);
  background: var(--surface-2) !important;
}
.ui-datatable .ui-column-filter:focus {
  outline: none; border-color: var(--primary) !important; box-shadow: 0 0 0 3px var(--ring);
}

/* body rows: hairline dividers only, no vertical lines, comfortable padding */
.ui-datatable tbody td,
.ui-datatable .ui-datatable-data > tr > td {
  border: 0 !important;
  border-bottom: 1px solid var(--border) !important;
  padding: 13px 16px !important;
  color: var(--text) !important;
  background: transparent !important;
  font-size: 13.5px;
  vertical-align: middle;
}
.ui-datatable tbody tr:last-child td,
.ui-datatable .ui-datatable-data > tr:last-child > td { border-bottom: 0 !important; }
/* hover: a soft highlighted band */
.ui-datatable tbody tr:hover td,
.ui-datatable .ui-datatable-data > tr:hover > td,
.ui-datatable tbody tr.ui-state-highlight td { background: var(--surface-2) !important; }
.ui-datatable .ui-sortable-column:hover { color: var(--text-2) !important; }
.ui-datatable .ui-sortable-column-icon { color: var(--text-3) !important; }
/* Sort indicator - another sprite the "none" theme drops, so sortable columns gave no
   hint they were sortable. */
.ui-datatable .ui-sortable-column-icon {
  background-image: none !important; text-indent: 0 !important; overflow: visible;
  width: auto !important; height: auto !important; margin: 0 0 0 5px; vertical-align: middle;
  font-family: 'primeicons'; font-style: normal; font-weight: normal; line-height: 1;
}
.ui-datatable .ui-sortable-column-icon:before { content: '\e99e'; font-size: 11px; }
/* monospaced reference / number cells (left-aligned; add styleClass="ie-num") */
.ui-datatable .ie-num { font-family: var(--font-mono); font-weight: 700; }
.ui-datatable .ui-datatable-empty-message,
.ui-datatable .ui-datatable-data-empty {
  text-align: center !important; color: var(--text-3) !important; padding: 26px !important;
  background: transparent !important; border: 0 !important;
}

/* ---- Paginator: minimal pill controls ---- */
.ui-paginator {
  background: transparent !important; border: 0 !important;
  border-top: 1px solid var(--border) !important; padding: 12px 4px 2px !important; text-align: center;
}
.ui-paginator .ui-paginator-page,
.ui-paginator .ui-paginator-next, .ui-paginator .ui-paginator-prev,
.ui-paginator .ui-paginator-first, .ui-paginator .ui-paginator-last {
  background: var(--surface) !important; border: 1px solid var(--border) !important;
  border-radius: var(--radius-sm) !important; color: var(--text-2) !important;
  min-width: 32px; height: 32px; line-height: 30px; font-weight: 700; margin: 0 2px; cursor: pointer;
}
.ui-paginator .ui-paginator-page.ui-state-active {
  background: var(--primary) !important; border-color: var(--primary) !important; color: var(--on-primary) !important;
}
.ui-paginator .ui-paginator-page:not(.ui-state-active):hover,
.ui-paginator .ui-paginator-next:hover, .ui-paginator .ui-paginator-prev:hover { background: var(--surface-3) !important; }
.ui-paginator .ui-paginator-rpp-options {
  border: 1px solid var(--border) !important; border-radius: var(--radius-sm) !important;
  background: var(--surface) !important; padding: 4px 6px; height: 32px; margin-left: 6px;
}
/* The first/prev/next/last glyphs come from the jQuery-UI sprite, which the "none" theme
   omits, so the buttons render blank. We substitute chevron characters via ::before.

   The catch: PrimeFaces also puts a one-letter fallback label inside the span -
   <span class="ui-icon ui-icon-seek-first">F</span> - which the sprite CSS normally hides
   with text-indent:-99999px. Undoing that indent to reveal our chevron also revealed the
   letter, so the controls read "«F  ‹P  ›N  »E". font-size:0 collapses the letter while
   the ::before sets its own size, so only the chevron shows. */
.ui-paginator .ui-icon {
  text-indent: 0 !important; background-image: none !important; overflow: visible;
  font-size: 0 !important;
}
.ui-paginator .ui-icon:before { font-size: 15px; line-height: 30px; color: inherit; }
.ui-paginator .ui-paginator-first .ui-icon:before { content: '\00AB'; }   /* « */
.ui-paginator .ui-paginator-prev  .ui-icon:before { content: '\2039'; }   /* ‹ */
.ui-paginator .ui-paginator-next  .ui-icon:before { content: '\203A'; }   /* › */
.ui-paginator .ui-paginator-last  .ui-icon:before { content: '\00BB'; }   /* » */

/* Disabled paging controls. PrimeFaces marks them ui-state-disabled (and tabindex=-1)
   when there is nowhere to page to - one page of results makes all four inert, which is
   correct but looked broken, because our button styling above painted them identically to
   live ones. Dim them and kill the pointer so "nothing happens" is visibly intentional. */
.ui-paginator .ui-state-disabled,
.ui-paginator a.ui-state-disabled {
  opacity: .45 !important; cursor: default !important; pointer-events: none;
}
.ui-paginator .ui-state-disabled:hover { background: var(--surface) !important; }

/* ---- Wizard (p:wizard): the step names as a row of pills over the form ----
   PrimeFaces draws its own step titles, nav bar and jQuery-UI chrome. The
   "none" theme leaves all of it unpainted, so without this the steps read as a
   bulleted list and the Back/Next buttons sit in a grey band. The shape follows
   the sheet's own .sd-wizard: the current step in the brand tint, the rest
   quiet, one hairline under the row. */
.ui-wizard { background: transparent !important; border: 0 !important; }
.ui-wizard .ui-wizard-step-titles {
	display: flex; flex-wrap: wrap; gap: 8px; list-style: none;
	margin: 0 0 20px; padding: 0 0 16px;
	border-bottom: 1px solid var(--border); background: transparent !important;
}
.ui-wizard .ui-wizard-step-title {
	float: none !important;
	background: var(--surface-2) !important; border: 1px solid var(--border) !important;
	border-radius: var(--radius-full) !important; color: var(--text-3) !important;
	padding: 7px 15px !important; font-size: 12.5px; font-weight: 700;
}
.ui-wizard .ui-wizard-step-title.ui-state-highlight {
	background: var(--primary-soft) !important; border-color: var(--primary) !important;
	color: var(--primary-press) !important;
}
.ui-wizard .ui-wizard-content { background: transparent !important; border: 0 !important; padding: 0 !important; }
.ui-wizard .ui-wizard-navbar {
	display: flex; gap: 10px; justify-content: flex-end;
	margin-top: 22px; padding-top: 16px;
	border-top: 1px solid var(--border); background: transparent !important;
}

/* ---- Dialog (p:dialog) ---- */
.ui-dialog {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  /* Nothing capped the height, and `overflow: hidden` above hides whatever spills - so a
     dialog taller than the window was silently CLIPPED rather than scrolled. The user
     dialog is the one that trips it: 21 role checkboxes make it ~920px, which overflows
     any laptop viewport, and the Cancel/Save buttons sit below them. The result was a
     dialog you could open but not complete, and PrimeFaces pinning it to top:0 (it centres
     from the measured height) made it look broken as well. Cap to the viewport here and
     let the body scroll below. */
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
}
.ui-dialog .ui-dialog-titlebar {
  background: var(--surface); color: var(--text); border: none;
  border-bottom: 1px solid var(--border); font-weight: 800; padding: 18px 22px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.ui-dialog .ui-dialog-title { font-size: 16px; font-weight: 800; letter-spacing: -.3px; }
/* The scrolling region. 130px is the titlebar (~57px) plus the 32px viewport margin above
   with room to spare, so the header stays put and only the body moves. */
.ui-dialog .ui-dialog-content {
  background: var(--surface); color: var(--text-2); padding: 22px;
  max-height: calc(100vh - 130px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The titlebar close control. Its glyph is a jQuery-UI sprite that the "none" theme
   omits, so the X was an invisible 16px box and the dialog looked uncloseable - the
   footer Close button was the only way out, and dialogs without one had none at all.
   Same fix as the paginator above, but drawn from the vendored PrimeIcons font. */
.ui-dialog .ui-dialog-titlebar-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: none; margin: 0;
  border: none; border-radius: var(--radius-sm);
  color: var(--text-3); text-decoration: none;
}
.ui-dialog .ui-dialog-titlebar-close:hover { background: var(--surface-3); color: var(--text); }
.ui-dialog .ui-dialog-titlebar-close .ui-icon {
  background-image: none !important; text-indent: 0 !important; overflow: visible;
  width: auto; height: auto; margin: 0;
  font-family: 'primeicons'; font-style: normal; font-weight: normal; line-height: 1;
}
.ui-dialog .ui-dialog-titlebar-close .ui-icon:before { content: '\e90b'; font-size: 13px; }

/* p:dialog renders its footer facet with only ui-widget-content, which the "none"
   theme leaves unstyled - the Close button sat flush against the content with no
   separation. */
.ui-dialog .ui-dialog-footer {
  background: var(--surface-2); border: none; border-top: 1px solid var(--border);
  padding: 14px 22px; display: flex; align-items: center; justify-content: flex-end; gap: 8px;
}
.ui-dialog .ui-dialog-footer > span { display: flex; gap: 8px; }

.ui-widget-overlay { background: rgba(15,13,11,.5); }

/* ---- Messages / growl (p:messages, p:growl) ---- */
.ui-messages, .ui-message, .ui-growl-item {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  font-weight: 600;
}
.ui-messages-info, .ui-message-info, .ui-growl-item.ui-growl-info { background: var(--info-soft); color: var(--info); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.ui-messages-warn, .ui-message-warn { background: var(--warning-soft); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.ui-messages-error, .ui-message-error { background: var(--danger-soft); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.ui-messages-success, .ui-message-success { background: var(--success-soft); color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); }

/* ---- Tabs (p:tabView) ---- */
.ui-tabs .ui-tabs-nav { background: transparent; border: none; border-bottom: 1px solid var(--border); }
.ui-tabs .ui-tabs-nav li { background: transparent; border: none; margin-bottom: -1px; }
.ui-tabs .ui-tabs-nav li a { color: var(--text-3); font-weight: 700; border: none; border-bottom: 2px solid transparent; padding: 14px 12px; }
.ui-tabs .ui-tabs-nav li.ui-state-active a { color: var(--text); border-bottom-color: var(--primary); }

/* ---- Progress bar ---- */
.ui-progressbar { background: var(--surface-3); border: none; border-radius: var(--radius-full); }
.ui-progressbar .ui-progressbar-value { background: var(--primary); border-radius: var(--radius-full); }

/* ---- Badges / tags (p:badge, p:tag) ---- */
.ui-badge, .ui-tag { background: var(--primary); color: var(--on-primary); border-radius: var(--radius-full); font-weight: 700; }
.ui-tag.ie-success { background: var(--success-soft); color: var(--success); }
.ui-tag.ie-warning { background: var(--warning-soft); color: var(--warning); }
.ui-tag.ie-danger  { background: var(--danger-soft);  color: var(--danger); }

/* The calendar button (showOn="button") and the spinner arrows were blank orange blocks
   in every browser. PrimeFaces 6.2 gives them jQuery-UI sprite classes, not PrimeIcons:
   the calendar.js trigger appends <span class="ui-icon ui-icon-calendar">, and the
   spinner renders <span class="ui-icon ui-icon-triangle-1-n|s">. The "none" theme has
   no sprite, so nothing was drawn. Draw the glyphs from the primeicons font (codepoints
   from primeicons.css: pi-calendar \e927, pi-chevron-up \e903, pi-chevron-down \e902). */
.ui-icon.ui-icon-calendar,
.ui-spinner .ui-spinner-button .ui-icon {
  background-image: none !important; text-indent: 0 !important; overflow: visible !important;
  font-family: 'primeicons'; font-style: normal; font-weight: normal; line-height: 1;
  speak: none; -webkit-font-smoothing: antialiased;
}
.ui-icon.ui-icon-calendar:before { content: '\e927'; }
.ui-spinner .ui-spinner-button .ui-icon.ui-icon-triangle-1-n:before { content: '\e903'; }
.ui-spinner .ui-spinner-button .ui-icon.ui-icon-triangle-1-s:before { content: '\e902'; }
.ui-button.ui-datepicker-trigger { margin-left: 6px; vertical-align: middle; }
/* The house .ui-button padding out-ranks PrimeFaces' own spinner sizing; give the two
   arrows back their half-height slots with the glyph centred in each. */
.ui-spinner .ui-spinner-button.ui-button {
  padding: 0; width: 24px; box-shadow: none;
  display: flex; align-items: center; justify-content: center;
}
.ui-spinner .ui-spinner-button .ui-button-text { padding: 0; display: flex; align-items: center; justify-content: center; }
/* The input took the house input width and overflowed its 110px wrapper under the arrows
   and the next control; keep it inside, with room on the right for the arrows. */
.ui-spinner { position: relative; display: inline-block; vertical-align: middle; }
.ui-spinner .ui-spinner-input.ui-inputfield { width: 100%; box-sizing: border-box; padding-right: 30px; }
.ui-spinner .ui-spinner-button .ui-icon { position: static; margin: 0; width: auto; height: auto; font-size: 10px; }
