/*
 * Remote Control account endpoint (.rc-*). Layered on the account DS
 * (css/enttec-account-ui.css + enttec-account-ds2.css), so it reuses the shared
 * --acct-* tokens and the .enttec-btn / .enttec-badge / .enttec-alert
 * components; this file only adds the panel-specific pieces. Enqueued only on
 * the endpoint and only when the feature is enabled.
 *
 * Three states share this sheet: the empty state, the keys table, and the
 * one-shot secret reveal. The reveal is the only screen that ever shows a full
 * key, which is why it is styled to look deliberately different from the rest
 * of the account area: it is a moment, not a page.
 */

/* ============================================================================
 * MAKE THE `hidden` ATTRIBUTE ACTUALLY WORK.
 *
 * The browser's own rule is [hidden] { display: none }, at the very bottom of
 * the cascade, so ANY class that sets `display` outranks it. .rc-pager sets
 * display:flex, which silently defeated pager.hidden = true and left a stale
 * "Showing 1 to 10 of 14" on screen under four filtered rows. Cost us two
 * rounds of the same bug, hence one central fix rather than per-component
 * [hidden] overrides.
 *
 * Scoped to this feature's own subtrees. .rc-confirm is appended to <body>, not
 * to #rc-root, so it needs its own selector.
 * ==========================================================================*/
#rc-root [hidden], .rc-confirm[hidden] { display: none !important; }

/* ============================================================================
 * SCROLLBAR: reserve its space, and tone it down.
 *
 * THE BUG THIS FIXES: opening the activity log shifted the whole page 3px left
 * and 12px narrower. Cause is the full-height rule immediately below, which
 * pins the page to exactly 100vh and so parks it precisely on the threshold
 * where no scrollbar is needed. Any content growth tips it over, the scrollbar
 * claims 15px of width, and everything reflows sideways.
 *
 * scrollbar-gutter: stable reserves that 15px permanently, so the space is
 * there whether the bar is or not and nothing can move. This is the fix rather
 * than forcing `overflow-y: scroll`, which would reserve the space but also
 * show a permanently visible dead scrollbar.
 *
 * Scoped with :has() so it applies to the document scroller (html) but ONLY on
 * this endpoint. Restyling the scrollbar site-wide is a bigger design decision
 * than this branch should make on its own; if we want it everywhere it belongs
 * in the account DS, not here.
 * ==========================================================================*/
html:has(body.rc-endpoint) {
	scrollbar-gutter: stable;
	/* Standard properties (Chrome 121+, Firefox, Safari 18.2+). A hairline
	 * thumb in the DS border grey on a transparent track, so it reads as part
	 * of the page rather than an OS artefact. */
	scrollbar-width: thin;
	scrollbar-color: var(--acct-border) transparent;
}
/* Fallback for engines predating the standard properties above. The transparent
 * border plus background-clip is what makes the thumb a slim inset pill rather
 * than filling the full track width. */
html:has(body.rc-endpoint)::-webkit-scrollbar { width: 12px; height: 12px; }
html:has(body.rc-endpoint)::-webkit-scrollbar-track { background: transparent; }
html:has(body.rc-endpoint)::-webkit-scrollbar-thumb {
	background-color: var(--acct-border);
	border-radius: var(--acct-radius-pill);
	border: 3px solid transparent;
	background-clip: content-box;
}
html:has(body.rc-endpoint)::-webkit-scrollbar-thumb:hover { background-color: #b0b6bc; }

/* Full-height page on this endpoint only (body.rc-endpoint). A flex chain from
 * <main> down lets the white account content card stretch to the viewport
 * bottom, so a short empty state still reads as a full page instead of a card
 * floating above dead space. Scoped to rc-endpoint so no other account page is
 * affected. */
body.rc-endpoint main { display: flex; flex-direction: column; min-height: 100vh; }
body.rc-endpoint main > section,
body.rc-endpoint main > section > article,
body.rc-endpoint article > .woocommerce,
body.rc-endpoint #enttec-account.acct-ds2 { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
body.rc-endpoint #enttec-account.acct-ds2 .my-account-row { flex: 1 1 auto; }
@media (min-width: 992px) {
	body.rc-endpoint #enttec-account.acct-ds2 .woocommerce-MyAccount-content { min-height: 100%; display: flex; flex-direction: column; }
}

/* The content now varies in height (a table grows with the number of devices),
 * so nothing is height-locked. Instead #rc-root grows to fill whatever the
 * column gives it, and only the empty state stretches inside that. */
/* One monospace stack and one size for every machine-readable value on this
 * page (masked keys, hostnames, device IDs). They sit in adjacent columns, so
 * a half-pixel size difference between them reads as an accident rather than a
 * decision. Declared once here; nothing below restates the stack. */
/* On :root rather than on #rc-root, because the revoke popover is appended to
 * <body> and would otherwise fall outside the scope and render its masked key in
 * the body font. This sheet is enqueued only on this endpoint, so :root is
 * effectively page scope. Declared once here; nothing below restates the stack. */
:root {
	--rc-mono: ui-monospace, 'Cascadia Code', Menlo, Consolas, monospace;
	--rc-mono-size: 14px;
}

#rc-root {
	/* One knob for row density. The table can now run to ten rows plus a toolbar
	 * and a pager, so the original 14px made the panel taller than the viewport
	 * on a laptop. Change this, not the individual td rules. */
	--rc-row-pad-y: 9px;
	display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0;
}

/* ============================================================================
 * PAGE TITLE
 *
 * .page-title is shared with the licenses page, but its SIZE (32px, dropping to
 * 24px on the same 991px step the account grid uses) is declared in
 * css/licenses-redesign.css, which is enqueued only on that page. So on this
 * endpoint the heading fell back to the theme's generic h2 at 20px and read as a
 * section heading rather than a page title.
 *
 * Restated here rather than moved into the account DS, because promoting a page
 * title scale into the DS would touch every account page and is a bigger call
 * than this branch should make. Values copied from licenses-redesign.css; if
 * that page's title ever changes, this has to follow. The right long-term fix is
 * one .page-title rule in enttec-account-ds2.css that both pages read.
 * ==========================================================================*/
#enttec-account .page-title { font-size: 32px; line-height: 1.2; margin: 0 0 32px; }
@media (max-width: 991px) {
	#enttec-account .page-title { font-size: 24px; margin-bottom: 24px; }
}

/* Visually hidden but available to screen readers (table caption, "Actions"). */
.rc-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ============================================================================
 * PANEL (keys table)
 * ==========================================================================*/

.rc-panel { border: 1px solid var(--acct-border-soft); border-radius: var(--acct-radius-lg); background: #fff; box-shadow: var(--acct-shadow-sm); padding: 22px 24px 24px; }
.rc-panel__head { display: flex; align-items: center; justify-content: space-between; gap: 16px 24px; margin-bottom: 16px; }
/* 18px and no bottom margin since the intro line under it was removed (Kim, 2026-09-30):
 * the title alone now carries the row, centred against the Refresh button. */
.rc-panel__head h3 { font-family: var(--acct-font-head); font-weight: 600; font-size: 18px; color: var(--acct-text); margin: 0; }
.rc-panel__head h3 + p { margin-top: 4px; }
.rc-panel__head p { margin: 0; font-size: 13px; color: var(--acct-text-muted); line-height: 1.5; max-width: 54ch; }
/* Refresh and Generate live in the panel header. Generate used to sit in a form
 * below the table, which put the page's primary action underneath ten rows of
 * content and off the bottom of the screen. */
.rc-panel__actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
/* Standard (md) size since 2026-09-30, so the page's main actions are not smaller
 * than the status filter beside them. A label never breaks onto two lines. */
.rc-panel__actions .enttec-btn { white-space: nowrap; }

/* ============================================================================
 * TOOLBAR (search + status filter)
 *
 * Matches the licenses page's software table rather than inventing a second
 * pattern: pill-shaped search on the left, a pill dropdown trigger beside it,
 * and a custom menu instead of a native <select> so the option rows can carry
 * per-status counts. Class names are the licenses page's own
 * (.filter-dropdown-*, .dropdown-*-custom) so the two read as one component
 * and can be promoted into the account DS together later.
 * ==========================================================================*/

.rc-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }

.rc-search { position: relative; flex: 1 1 260px; min-width: 0; }
#enttec-account .rc-search input[type="text"] {
	width: 100%; height: 38px; margin: 0; padding: 0 34px 0 36px;
	border: 1px solid var(--acct-border); border-radius: var(--acct-radius-pill);
	background: #fafafa; font-family: var(--acct-font-body); font-size: 13.5px; color: var(--acct-text);
	transition: border-color var(--acct-dur) var(--acct-ease), box-shadow var(--acct-dur) var(--acct-ease), background var(--acct-dur) var(--acct-ease);
}
#enttec-account .rc-search input[type="text"]:focus { outline: none; background: #fff; border-color: var(--acct-blue); box-shadow: var(--acct-ring-soft); }
.rc-search .ico { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--acct-text-muted); display: flex; pointer-events: none; font-size: 13px; }
/* The theme turns every bare <button> in the account area into a full-size blue
 * pill, so both toolbar buttons need the #enttec-account prefix (1,2,0) to
 * outrank it (0,3,1) and be plain again. */
#enttec-account .rc-search-clear {
	position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
	appearance: none; width: auto; min-width: 0; height: auto; margin: 0; padding: 4px;
	background: transparent; border: 0; box-shadow: none;
	color: var(--acct-text-muted); border-radius: 50%; display: flex; line-height: 0; cursor: pointer;
}
#enttec-account .rc-search-clear:hover { background: transparent; color: var(--acct-text-2); }
#enttec-account .rc-search-clear:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); }

.filter-dropdown-wrapper { position: relative; flex: 0 0 auto; }
#enttec-account .filter-dropdown-trigger {
	display: inline-flex; align-items: center; gap: 8px;
	appearance: none; width: auto; min-width: 0; height: 38px; margin: 0; padding: 0 16px;
	background: #fafafa; border: 1px solid var(--acct-border); box-shadow: none;
	color: var(--acct-text-3); border-radius: var(--acct-radius-pill);
	font-family: var(--acct-font-body); font-weight: 500; font-size: 13.5px;
	text-transform: none; letter-spacing: 0; line-height: 1.2; cursor: pointer;
	transition: background var(--acct-dur) var(--acct-ease), border-color var(--acct-dur) var(--acct-ease);
}
#enttec-account .filter-dropdown-trigger:hover { background: #f0f0f0; border-color: #b0b0b0; color: var(--acct-text-3); }
#enttec-account .filter-dropdown-trigger:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); }
.filter-dropdown-trigger .chevron { display: flex; font-size: 11px; transition: transform var(--acct-dur) var(--acct-ease); }
.filter-dropdown-wrapper.open .chevron { transform: rotate(180deg); }

/* No count badge on the trigger. It duplicated the count line under the table
 * and, being a filled pill, read as an alert rather than as information. The
 * count now lives in exactly one place and is always shown. */
.dropdown-menu-custom {
	position: absolute; top: calc(100% + 6px); left: 0; z-index: 20;
	min-width: 216px; padding: 6px; display: none;
	background: #fff; border: 1px solid var(--acct-border-soft);
	border-radius: var(--acct-radius); box-shadow: 0 8px 24px rgba(16, 24, 40, .12);
}
.filter-dropdown-wrapper.open .dropdown-menu-custom { display: block; animation: rcDropIn .14s var(--acct-ease) both; }
@keyframes rcDropIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.dropdown-item-custom { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 10px; border-radius: var(--acct-radius-sm); font-size: 13.5px; color: var(--acct-text-2); cursor: pointer; }
.dropdown-item-custom:hover { background: var(--acct-surface-2); }
.dropdown-item-custom .n { color: var(--acct-text-muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
/* The tick replaces the count on the active row: showing both put two numbers
 * and a glyph in one 216px line. */
.dropdown-item-custom .check-icon { display: none; color: var(--acct-blue); font-size: 12px; }
.dropdown-item-custom.active { color: var(--acct-text); font-weight: 600; }
.dropdown-item-custom.active .check-icon { display: flex; }
.dropdown-item-custom.active .n { display: none; }

/* ============================================================================
 * TABLE
 * Desktop: a real table. Mobile: each row becomes a card and every cell grows
 * its own label from the data-label attribute, so the column headings do not
 * have to be repeated in the markup.
 * ==========================================================================*/

/* Same subtle treatment for the two inner scrollers (the table at narrow
 * desktop widths, and a long key in the reveal field), so a scrollbar appearing
 * anywhere on this page looks like the same thing. */
.rc-tablewrap, .rc-key { scrollbar-width: thin; scrollbar-color: var(--acct-border) transparent; }
.rc-tablewrap::-webkit-scrollbar, .rc-key::-webkit-scrollbar { width: 10px; height: 10px; }
.rc-tablewrap::-webkit-scrollbar-track, .rc-key::-webkit-scrollbar-track { background: transparent; }
.rc-tablewrap::-webkit-scrollbar-thumb, .rc-key::-webkit-scrollbar-thumb {
	background-color: var(--acct-border);
	border-radius: var(--acct-radius-pill);
	border: 3px solid transparent;
	background-clip: content-box;
}

.rc-tablewrap { overflow-x: auto; }

/* table-layout: fixed pins every column to its <colgroup> width instead of
 * letting the browser compute widths from whatever happens to be rendered.
 *
 * It is load-bearing, not cosmetic. With auto layout the grid moves constantly:
 * filter to Connected and no row has a Revoke button, so the action column
 * collapses and all five columns reflow. Same between pages (page 1 has
 * hostnames, page 2 may not) and while sorting. Fixed layout also keeps the
 * action column's width when it is empty, which is what Kim reported. */
.rc-table { width: 100%; border-collapse: collapse; font-size: 14px; table-layout: fixed; }
.rc-table th { text-align: left; font-family: var(--acct-font-body); font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--acct-text-muted); padding: 0 14px 8px 0; border-bottom: 1px solid var(--acct-border-soft); white-space: nowrap; }

/* Sortable headings, copied from the licenses page spec exactly so the arrows
 * are the ones Kim already knows: fa-sort while neutral, fa-sort-up /
 * fa-sort-down while active, 11px, #9ca3af at .6 opacity, and the whole heading
 * turns ENTTEC blue while it is the sorted column. */
.rc-table th.sortable { cursor: pointer; user-select: none; }
.rc-table th.sortable:hover { color: var(--acct-text-2); }
.rc-table th.sortable:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); border-radius: 4px; }
.rc-table th.sortable .sort-arrow { display: inline-block; margin-left: 6px; font-size: 11px; color: #9ca3af; opacity: .6; transition: opacity .15s, color .15s; }
.rc-table th.sortable:hover .sort-arrow { opacity: 1; color: #6b7280; }
.rc-table th.sortable.sort-asc, .rc-table th.sortable.sort-desc { color: var(--acct-blue); }
.rc-table th.sortable.sort-asc .sort-arrow, .rc-table th.sortable.sort-desc .sort-arrow { opacity: 1; color: var(--acct-blue); }

/* vertical-align: middle, because most cells are one line and only some are
 * two. Top-aligning meant a single badge floated at the ceiling of a row whose
 * neighbour had a value plus a sub-line. Centring fixes it without special
 * casing any status. */
.rc-table td { padding: var(--rc-row-pad-y) 14px var(--rc-row-pad-y) 0; border-bottom: 1px solid var(--acct-border-soft); vertical-align: middle; }
.rc-table tbody tr:last-child td { border-bottom: 0; }
.rc-table td:last-child, .rc-table th:last-child { text-align: right; }

/* The first column carries 5px of LEFT padding purely to clear the name input's
 * FOCUS RING, which is a box-shadow and so paints 3px OUTSIDE the border.
 * .rc-tablewrap is overflow-x: auto, so anything at negative x gets clipped,
 * and the ring was being sliced down its left edge (Kim: "the ui cuts on the
 * left side"). 5px leaves the 3px ring 2px of slack for sub-pixel rounding.
 *
 * The masked key and the name box then have to be brought back onto one text
 * edge, which is what the next two rules do:
 *   masked key : 5 (cell) + 6 (its own padding)          = 11
 *   name input : 5 (cell) + 1 (border) + 5 (its padding) = 11
 * Change any one of those numbers and the others have to move with it. */
.rc-table td:first-child, .rc-table th:first-child { padding-left: 5px; }
.rc-table th[data-col="key"] { padding-left: 11px; }

/* Key and Device share family, size and weight. The ONE deliberate difference
 * is letter-spacing: a masked key is a grouped code that gets read and compared
 * character by character, so it wants air, whereas a hostname is read as a word
 * and spacing it out makes it harder to parse. */
.rc-masked { display: block; padding-left: 6px; font-family: var(--rc-mono); font-size: var(--rc-mono-size); font-weight: 600; letter-spacing: 1px; color: var(--acct-text); white-space: nowrap; }
.rc-host { display: block; font-family: var(--rc-mono); font-size: var(--rc-mono-size); font-weight: 600; color: var(--acct-text); word-break: break-all; }
/* A connected S-PLAY's name opens its remote address. Blue at rest so it reads
 * as a link without an underline in a dense table; underline on hover/focus. */
a.rc-host--link { color: var(--acct-blue); text-decoration: none; text-underline-offset: 2px; transition: color .15s ease; }
/* Colour restated on hover: the theme's own a:hover would otherwise recolour it. */
#enttec-account a.rc-host--link:hover, #enttec-account a.rc-host--link:focus-visible { color: var(--acct-blue); text-decoration: underline; }
a.rc-host--link:focus-visible { outline: 2px solid var(--acct-blue); outline-offset: 2px; border-radius: 3px; }
@media (prefers-reduced-motion: reduce) { a.rc-host--link { transition: none; } }
/* Secondary line under either of the above: the customer's own note, or the
 * device ID. Body font on purpose, so it reads as a caption not a value. */
.rc-sub { display: block; margin-top: 1px; font-size: 12.5px; color: var(--acct-text-muted); }
.rc-muted { color: var(--acct-text-muted); }
/* Shared by the table cell and the reveal panel's inline "Expires in <b>".
 * Only the table wants it on its own line; inline elsewhere. */
.rc-countdown { font-weight: 600; color: var(--acct-text); font-variant-numeric: tabular-nums; }
.rc-table .rc-countdown { display: block; }
/* Under an hour left. Colour is a reinforcement, never the only signal: the
 * text itself already counts down. */
.rc-countdown.is-low { color: var(--acct-danger-text); }
/* Breathing room on the right so Revoke is not flush against the cell edge.
 * Applied to the cell rather than as a margin on the button, so the mobile card
 * layout (which right-aligns the same button) inherits it too. */
.rc-actioncell { white-space: nowrap; }
.rc-table td.rc-actioncell { padding-right: 8px; }
.rc-table tbody tr { transition: background var(--acct-dur) var(--acct-ease); }
.rc-table tbody tr:hover { background: var(--acct-surface-2); }

/* ============================================================================
 * EDITABLE KEY NAME, WITH NO LAYOUT SHIFT
 *
 * The read view (<span>) and the edit view (<input>) share IDENTICAL box
 * metrics: same font-size, same line-height, same padding, and a 1px border
 * that is merely transparent when not editing. Swapping one for the other
 * therefore moves nothing by a single pixel, which is the entire point (Kim:
 * "make sure the UI doesnt move around too much when it becomes an input
 * field"). The duplicated numbers below are deliberate, do not "tidy" them into
 * one rule that only covers one of the two elements.
 * ==========================================================================*/

.rc-name, #enttec-account .rc-name-input {
	/* max-width: 100%, not a pixel value: the column is a fixed share of the
	 * table now, so the name box follows the column instead of fighting it. */
	display: block; width: 100%; max-width: 100%; box-sizing: border-box;
	font-family: var(--acct-font-body); font-size: 12.5px; line-height: 18px;
	padding: 1px 5px; border: 1px solid transparent; border-radius: 5px;
	margin: 1px 0 0 0; min-height: 0; height: auto;
}
/* Renaming is a rare action, so it gets a rare amount of visual weight.
 *
 * The name is plain muted text. Nothing lights up on ROW hover, because
 * outlining a box on all ten rows as the pointer travels down the table
 * advertises a feature almost nobody uses and makes the table feel busy. The
 * only affordance is a faint tint when the pointer is directly on the name, plus
 * the pencil pointer below and a title. Quiet, but discoverable to anyone who tries.
 *
 * Still NO pencil icon in the row: the earlier one sat beside the KEY while
 * editing the NAME, so it pointed at the wrong thing, and one per row was noise
 * regardless. That decision stands; the affordance moved into the pointer.
 *
 * WHY A CUSTOM POINTER AND NOT `cursor: text`. The I-beam was what this used,
 * and it reads as "there is text here", not "you can change this": it is the
 * same pointer the customer gets over any paragraph on the page. A pencil says
 * editable without costing a pixel of layout, which is what ruled the icon out.
 * The SVG is inline so it needs no request and cannot 404, drawn white-filled
 * with a dark stroke so it stays visible on both the row tint and white. The
 * `3 19` is the hotspot in image pixels, putting the click point on the pencil
 * TIP rather than the top-left of the box. `text` stays as the fallback for any
 * browser that refuses the URL, so the old behaviour is the floor, not nothing. */
.rc-name {
	color: var(--acct-text-muted);
	cursor: text;
	background: transparent; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background var(--acct-dur) var(--acct-ease);
}
/* The pencil, and it needs the #enttec-account prefix to land.
 *
 * The name span carries role="button" for the keyboard, and the Bootstrap
 * reboot in the stack ships `[role=button]{cursor:pointer}`. That is (0,1,0),
 * exactly the same specificity as a bare `.rc-name`, and it loads later, so it
 * won on source order and the field showed a hand. The prefix makes this (1,1,0)
 * and settles it without !important. Same trick, and the same reason, as the
 * .rc-name-input rule below.
 *
 * The data URI is PERCENT-ENCODED. A raw `<` makes the declaration invalid and
 * the browser drops the whole thing silently. `text` stays as the fallback for
 * anything that refuses the URL, so the old behaviour is the floor. `3 19` puts
 * the click point on the pencil tip rather than the corner of the image. */
#enttec-account .rc-name {
	cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='22'%20height='22'%3E%3Cpath%20d='M3%2019l4.2-1.1L18.8%206.3a2.1%202.1%200%200%200-3-3L4.1%2014.9z'%20fill='%23fff'%20stroke='%2315181b'%20stroke-width='1.6'%20stroke-linejoin='round'/%3E%3Cpath%20d='M14.3%204.8l3%203'%20stroke='%2315181b'%20stroke-width='1.6'/%3E%3C/svg%3E") 3 19, text;
}
.rc-name:hover { background: var(--acct-surface-2); }
.rc-name:focus-visible { outline: none; background: var(--acct-surface-2); box-shadow: var(--acct-ring-soft); }
.rc-name.is-empty { color: #b3b9bf; font-style: italic; }
#enttec-account .rc-name-input { color: var(--acct-text); background: #fff; border-color: var(--acct-blue); box-shadow: var(--acct-ring-soft); outline: none; }

/* ============================================================================
 * "HERE IS THE ONE YOU JUST MADE"
 *
 * After generating, a new row appears among up to nine others and the customer
 * has no way to tell which is theirs. Change blindness is real: people miss a
 * change they did not watch happen. So the new row holds a tint for ~4.5s and
 * then fades out.
 *
 * No left accent bar: it pulled the eye to the table's edge rather than to the
 * row. The tint alone is enough, and it survives colour vision deficiency
 * because it is a lightness change rather than a hue-only one. Under reduced
 * motion the fade is replaced by a static tint that the JS still clears on its
 * timer, so nothing is ever signalled by motion alone.
 * ==========================================================================*/

.rc-table tbody tr.is-new { animation: rcNewRow 4.5s var(--acct-ease) both; }
@keyframes rcNewRow {
	0%, 55% { background: #e3f4fc; }
	100%    { background: transparent; }
}

/* ============================================================================
 * NO RESULTS / PAGER
 * ==========================================================================*/

.rc-noresults { padding: 40px 20px; text-align: center; color: var(--acct-text-muted); font-size: 14px; }
#enttec-account .rc-noresults .enttec-btn { margin-top: 14px; }

.rc-pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--acct-border-soft); }
.rc-pager__count { font-size: 12.5px; color: var(--acct-text-muted); font-variant-numeric: tabular-nums; }
.rc-pager__nav { display: flex; align-items: center; gap: 4px; }
/* Not .enttec-btn: page numbers are a numeric strip, so they want equal square
 * cells rather than the DS button's text padding. Same reset dance against the
 * theme's blanket account-button rule as the toolbar controls. */
#enttec-account .rc-page {
	appearance: none; min-width: 32px; width: auto; height: 32px; margin: 0; padding: 0 8px;
	display: inline-flex; align-items: center; justify-content: center;
	border: 1px solid var(--acct-border); background: #fff; box-shadow: none;
	border-radius: var(--acct-radius-sm);
	font-family: var(--acct-font-body); font-size: 13px; font-weight: 600;
	text-transform: none; letter-spacing: 0; line-height: 1.2;
	color: var(--acct-text-2); cursor: pointer; font-variant-numeric: tabular-nums;
	transition: background var(--acct-dur) var(--acct-ease), border-color var(--acct-dur) var(--acct-ease), color var(--acct-dur) var(--acct-ease);
}
#enttec-account .rc-page:hover:not(:disabled):not(.is-current) { background: #fff; border-color: var(--acct-blue); color: var(--acct-blue); }
#enttec-account .rc-page:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); }
#enttec-account .rc-page.is-current { background: var(--acct-blue); border-color: var(--acct-blue); color: #fff; cursor: default; }
#enttec-account .rc-page:disabled { opacity: .45; cursor: not-allowed; }

/* Refresh feedback. Without it the button looks inert: the customer clicks, a
 * request goes out, and nothing visibly happens, because a refresh normally
 * finds nothing new. The icon spins while in flight and the button is
 * pointer-disabled so it cannot be double-fired.
 *
 * Under reduced motion the spin is off, so the dimmed non-interactive button IS
 * the feedback. Never motion as the only signal. */
.rc-refreshing { opacity: .65; pointer-events: none; }
.rc-refreshing i { animation: rcSpin .7s linear infinite; transform-origin: 50% 50%; }

/* Cards below 992px, NOT at a viewport width picked by eye. 992 is where the
 * account layout itself switches between one and two columns, and what breaks
 * the table is the width of the CONTENT COLUMN, not the window. Choosing a
 * lower number (780 first time round) left a band of tablet widths where the
 * sidebar was still taking its share and five columns were crushed into ~400px,
 * hyphenating hostnames mid-word. Keep this number in step with the account
 * grid's breakpoint. */
@media (max-width: 991px) {
	.rc-table, .rc-table tbody, .rc-table tr, .rc-table td { display: block; width: 100%; }
	.rc-table thead { display: none; }
	.rc-table tr { border: 1px solid var(--acct-border-soft); border-radius: var(--acct-radius); padding: 12px 14px; margin-bottom: 12px; background: #fff; }
	.rc-table tr:hover { background: #fff; }
	/* Grid, not flex, so the label holds column 1 while EVERY value in the cell
	 * stacks down column 2. With flex the masked key and its name sat on one
	 * line and the name got clipped off the edge. */
	.rc-table td { border: 0; padding: 6px 0; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 14px; align-items: baseline; text-align: right; }
	.rc-table td::before { content: attr(data-label); grid-column: 1; grid-row: 1; font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--acct-text-muted); text-align: left; }
	.rc-table td > * { grid-column: 2; justify-self: end; }
	.rc-table td:empty { display: none; }
	.rc-table td.rc-actioncell { padding-top: 10px; }
	.rc-table tr:last-child td { padding-bottom: 6px; }
	/* The desktop focus-ring clearance and its matching 6px indent are both
	 * pointless once cells are right-aligned cards, and the indent would push
	 * the key off the right edge. Reset both. */
	.rc-table td:first-child, .rc-table th:first-child { padding-left: 0; }
	.rc-masked { padding-left: 0; }
	/* Monospace values have no natural break points, so let them wrap rather
	 * than push the card wider than the screen. */
	.rc-masked, .rc-host { word-break: break-all; }
	.rc-masked, .rc-host, .rc-sub, .rc-countdown { text-align: right; }
	.rc-name, #enttec-account .rc-name-input { text-align: right; }

	/* The toolbar controls go full width and stack, since a 260px search plus a
	 * filter pill will not sit side by side in a phone-width card list. */
	.rc-search { flex: 1 1 100%; }
	.filter-dropdown-wrapper { width: 100%; }
	#enttec-account .filter-dropdown-trigger { width: 100%; justify-content: space-between; }
	/* Head stacks so the two actions get real width instead of being squeezed
	 * beside the heading. */
	.rc-panel__head { flex-direction: column; align-items: flex-start; }
	.rc-panel__actions { width: 100%; }
	#enttec-account .rc-panel__actions .enttec-btn { flex: 1 1 auto; }
}

/* ============================================================================
 * REVOKE CONFIRM: an anchored popover, no backdrop.
 *
 * Copies the licenses page's auto-renew confirm (.popup-autorenew-confirm in
 * css/licenses-redesign.css): a small warm-amber panel that appears attached to
 * the control you clicked. Colours and metrics lifted verbatim so the two read
 * as one control rather than two takes on the same idea.
 *
 * Why not a full modal: dimming the whole page to confirm one row action is out
 * of proportion, and it hides the very table you are acting on. Why not an
 * inline row: it pushed the table around under the pointer.
 *
 * position: fixed is required, not preferred. .rc-tablewrap is overflow-x: auto,
 * so an absolutely positioned panel inside it would be clipped at the edges.
 * Fixed escapes that, at the cost of needing repositioning on scroll, which the
 * JS does. Same trade the licenses page makes.
 * ==========================================================================*/

.rc-confirm {
	position: fixed; z-index: 100001;         /* above #wpadminbar (99999) */
	width: 300px; max-width: calc(100vw - 24px);
	background: #fff8f1; border: 1px solid #f7c894; border-radius: 8px;
	padding: 10px 12px; font-family: var(--acct-font-body); font-size: 13px;
	line-height: 1.45; color: #4a2c0a;
	box-shadow: 0 8px 24px rgba(16, 24, 40, .14);
	animation: rcConfirmIn .16s var(--acct-ease) both;
}
.rc-confirm__msg { display: block; margin-bottom: 9px; }
.rc-confirm__msg b { display: block; margin-bottom: 2px; }
.rc-confirm__key { display: block; margin-top: 4px; font-family: var(--rc-mono); font-size: 12px; letter-spacing: .5px; }
.rc-confirm__actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
@keyframes rcConfirmIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* The panel lives on <body>, OUTSIDE #enttec-account, so the account DS's
 * `#enttec-account .enttec-btn` rules do not reach it. These re-state the
 * component for that one context. Sizing comes from the same --_btn-* knobs the
 * DS uses, so Cancel and Revoke key cannot drift apart (they did: 36px against
 * 28px, because my first pass put min-height on the colour variants instead of
 * on the size modifier). Token values match enttec-account-ui.css. */
.rc-confirm .enttec-btn {
	--_btn-h: 28px; --_btn-px: 10px; --_btn-fs: 12px; --_btn-gap: 5px;
	display: inline-flex; align-items: center; justify-content: center; gap: var(--_btn-gap);
	appearance: none; width: auto; margin: 0; min-height: var(--_btn-h); height: auto;
	padding: 0 var(--_btn-px); font-family: var(--acct-font-body); font-size: var(--_btn-fs);
	font-weight: 600; text-transform: none; letter-spacing: 0; line-height: 1.2;
	border: 1.5px solid transparent; border-radius: var(--acct-radius);
	background: transparent; box-shadow: none; cursor: pointer;
	transition: background var(--acct-dur) var(--acct-ease), border-color var(--acct-dur) var(--acct-ease), color var(--acct-dur) var(--acct-ease);
}
.rc-confirm .enttec-btn--neutral { background: #fff; color: var(--acct-text-2); border-color: var(--acct-border); }
.rc-confirm .enttec-btn--neutral:hover { background: var(--acct-surface-2); border-color: #b0b6bc; }
.rc-confirm .enttec-btn--danger { background: #fff; color: var(--acct-danger-text); border-color: var(--acct-danger-line); }
.rc-confirm .enttec-btn--danger:hover { background: var(--acct-danger-tint); color: var(--acct-danger); border-color: var(--acct-danger); }
.rc-confirm .enttec-btn:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); }

/* ============================================================================
 * TOAST. Confirmation for actions whose result is a row changing somewhere in a
 * long table, which is easy to miss. Also on <body>, hence the explicit font.
 * ==========================================================================*/

.rc-toast {
	position: fixed; left: 50%; bottom: 24px; z-index: 100001;
	transform: translateX(-50%) translateY(8px);
	background: var(--acct-success-tint); color: var(--acct-success-text);
	border: 1px solid var(--acct-success-line);
	padding: 9px 16px; border-radius: var(--acct-radius-pill);
	font-family: var(--acct-font-body); font-size: 13px; font-weight: 600;
	box-shadow: var(--acct-shadow-sm);
	opacity: 0; pointer-events: none;
	transition: opacity var(--acct-dur) var(--acct-ease), transform var(--acct-dur) var(--acct-ease);
}
.rc-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ============================================================================
 * EMPTY / ERROR STATES
 * ==========================================================================*/

.rc-empty { flex: 1 1 auto; min-height: 340px; display: flex; flex-direction: column; align-items: center; justify-content: center; border: 1px dashed var(--acct-border); border-radius: var(--acct-radius-lg); background: var(--acct-surface-2); padding: 32px 28px; text-align: center; }
/* Expired / error are real outcomes, not "nothing yet", so they get a solid
 * card matching the panel rather than the dashed placeholder. */
.rc-empty--solid { border: 1px solid var(--acct-border-soft); background: #fff; box-shadow: var(--acct-shadow-sm); }
.rc-empty .glyph { width: 48px; height: 48px; margin: 0 auto 12px; border-radius: 12px; background: #fff; border: 1px solid var(--acct-border-soft); display: flex; align-items: center; justify-content: center; color: var(--acct-blue); font-size: 20px; }
.rc-empty .glyph--warn { color: var(--acct-warning); border-color: var(--acct-warning-line); background: var(--acct-warning-tint); }
.rc-empty .glyph--danger { color: var(--acct-danger); border-color: var(--acct-danger-line); background: var(--acct-danger-tint); }
.rc-empty h3 { font-family: var(--acct-font-head); font-weight: 600; font-size: 17px; color: var(--acct-text); margin: 0 0 6px; }
.rc-empty p { margin: 0 auto 20px; font-size: 14px; color: var(--acct-text-3); max-width: 62ch; line-height: 1.6; }
/* The theme's `.woocommerce-account .woocommerce button` rule sets
 * align-self: flex-start (specificity 0,3,1), which pins the CTA to the left
 * edge of the centred empty state. The #enttec-account id prefix (1,2,0)
 * outranks it. No !important needed.
 *
 * center, not flex-end: the button used to sit inside a flex ROW next to the
 * name field, where flex-end meant "bottom aligned". It is now a direct child of
 * the centred column, so flex-end would mean "hard right". */
#enttec-account .rc-empty .enttec-btn { align-self: center; }

/* ============================================================================
 * ONE-SHOT REVEAL
 * The only screen that shows a full key. Styled as a distinct moment: a warm
 * warning band on top, the key at display size, and the device instructions
 * inline so the customer reads them before walking away from the screen.
 * ==========================================================================*/

.rc-reveal { border: 1px solid var(--acct-border-soft); border-radius: var(--acct-radius-lg); background: #fff; box-shadow: var(--acct-shadow-md); padding: 0 0 24px; overflow: hidden; }
.rc-reveal__warn { display: flex; gap: 12px; align-items: flex-start; padding: 14px 24px; background: var(--acct-warning-tint); border-bottom: 1px solid var(--acct-warning-line); color: var(--acct-warning); font-size: 13.5px; line-height: 1.55; }
.rc-reveal__warn i { margin-top: 2px; flex: 0 0 auto; }
.rc-reveal h3 { font-family: var(--acct-font-head); font-weight: 600; font-size: 16px; color: var(--acct-text); margin: 22px 24px 10px; }

/* ONE height for the key field and its Copy button, so they cannot drift apart.
 * align-items:stretch is not enough on its own: the theme's generic
 * `.woocommerce-account .woocommerce button` rule sets an explicit height on
 * every button, which wins over the flex stretch and left Copy shorter than the
 * field. Driving both from --rc-row-h fixes it at the source, and 48px splits
 * the difference (the field was 52, the button 44) while staying above the 44px
 * minimum touch target. */
.rc-keyrow { --rc-row-h: 48px; display: flex; gap: 10px; align-items: stretch; margin: 0 24px; }
.rc-key { flex: 1 1 auto; display: flex; align-items: center; min-height: var(--rc-row-h); padding: 0 18px; background: var(--acct-surface-2); border: 1px solid var(--acct-border); border-radius: var(--acct-radius); font-family: var(--rc-mono); font-size: 19px; font-weight: 600; letter-spacing: 2.5px; color: var(--acct-text); user-select: all; overflow-x: auto; white-space: nowrap; }
.rc-key:focus-visible { outline: none; border-color: var(--acct-blue); box-shadow: var(--acct-ring); }
.rc-copy { flex: 0 0 auto; position: relative; display: flex; }
/* --_btn-h is the design system's own height knob, so this works WITH the
 * button component rather than overriding its internals. The id prefix (1,2,0)
 * is needed to outrank #enttec-account .enttec-btn (1,1,0), which sets the
 * default; the explicit height then also beats the theme's button rule. */
#enttec-account .rc-copy .enttec-btn { --_btn-h: var(--rc-row-h); height: var(--rc-row-h); }
.rc-copy .copied { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 6px; background: var(--acct-success-tint); color: var(--acct-success-text); border: 1.5px solid var(--acct-success-line); border-radius: var(--acct-radius); opacity: 0; pointer-events: none; transition: opacity .2s; font-weight: 600; font-size: 13px; }
.rc-copy.copied .copied { opacity: 1; }

.rc-expiry { margin: 12px 24px 0; font-size: 13px; color: var(--acct-text-muted); }
.rc-expiry b { color: var(--acct-text); font-variant-numeric: tabular-nums; }
.rc-expiry b.is-low { color: var(--acct-danger-text); }

/* The label step. The customer is asked for a device name at the unit, not
 * here, and it becomes a permanent hostname, so it is spelled out before they
 * leave this screen rather than buried in a tooltip. */
.rc-steps { margin: 22px 24px 0; padding: 18px 20px; background: var(--acct-surface-2); border: 1px solid var(--acct-border-soft); border-radius: var(--acct-radius); }
.rc-steps h4 { font-family: var(--acct-font-head); font-weight: 600; font-size: 13.5px; color: var(--acct-text); margin: 0 0 10px; }
.rc-steps ol { margin: 0; padding-left: 20px; }
.rc-steps li { font-size: 13.5px; line-height: 1.65; color: var(--acct-text-3); margin-bottom: 6px; text-wrap: pretty; }
/* The theme styles bare <code> pink for editorial content; override it here so
 * the example device name reads as UI, not as a syntax-highlighted token. */
#enttec-account .rc-steps code { font-family: var(--rc-mono); font-size: 12.5px; color: var(--acct-text); background: #fff; border: 1px solid var(--acct-border-soft); border-radius: 4px; padding: 1px 5px; }

.rc-reveal__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px; margin: 22px 24px 0; padding-top: 18px; border-top: 1px solid var(--acct-border-soft); }
.rc-reveal__nudge { margin: 0; margin-right: auto; font-size: 13px; color: var(--acct-danger-text); max-width: 46ch; }

/* ============================================================================
 * ACTIVITY LOG (progressive disclosure: closed by default, it is reference
 * detail rather than something the customer came here to read)
 * ==========================================================================*/

.rc-activity { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--acct-border-soft); }
/* When the pager is on screen it already draws the rule that separates the
 * footer from the table, so the activity block must NOT draw a second one.
 *
 * Without this the panel ends in two horizontal rules 47px apart and the footer
 * carries ~64px more air than the prototype it was signed off from, because the
 * prototype had no activity log to stack underneath. The rule stays in the
 * default above for the case where the pager is hidden (a single unfiltered key),
 * where the activity toggle IS the first thing under the table and does need it.
 *
 * Keyed on :not([hidden]) rather than on a class, so it follows the pager's real
 * visibility with no JS involvement. */
.rc-pager:not([hidden]) + .rc-activity { margin-top: 12px; padding-top: 0; border-top: 0; }
.rc-activity summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--acct-text-muted); list-style: none; display: inline-flex; align-items: center; gap: 8px; padding: 4px 0; transition: color var(--acct-dur) var(--acct-ease); }
.rc-activity summary::-webkit-details-marker { display: none; }
.rc-activity summary::before { content: "\f105"; font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: 12px; transition: transform var(--acct-dur) var(--acct-ease); }
.rc-activity[open] summary::before { transform: rotate(90deg); }
/* Show older activity. Left-aligned under the list rather than centred, so it
 * reads as a continuation of the rows above it and not as a primary action. */
.rc-act__more { margin-top: 10px; }
.rc-activity summary:hover { color: var(--acct-blue); }
.rc-activity summary:focus-visible { outline: none; box-shadow: var(--acct-ring-soft); border-radius: 4px; }
.rc-act { list-style: none; margin: 12px 0 0; padding: 0; }
/* One line per event (Kim, 2026-09-30). The date column was 96px, narrower than
 * "30 Sept 2026 15:33", so the row wrapped into two. The date now keeps one
 * width that fits it and never wraps; a long description wraps inside its own
 * column. Phones (560px and under) still stack, in the media query below. */
.rc-act li { display: flex; flex-wrap: nowrap; align-items: baseline; gap: 4px 14px; padding: 7px 0; border-bottom: 1px solid var(--acct-border-soft); font-size: 13px; }
.rc-act li:last-child { border-bottom: 0; }
.rc-act__when { flex: 0 0 136px; white-space: nowrap; color: var(--acct-text-muted); font-variant-numeric: tabular-nums; }
.rc-act__what { flex: 1 1 0; min-width: 0; color: var(--acct-text-3); overflow-wrap: anywhere; }

/* ============================================================================
 * MOTION
 * ==========================================================================*/

.rc-enter { animation: rcIn .32s var(--acct-ease) both; }
@keyframes rcIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.rc-spin { display: inline-block; width: 22px; height: 22px; border-radius: 50%; border: 2px solid rgba(14, 165, 223, .3); border-top-color: var(--acct-blue); animation: rcSpin .7s linear infinite; }
@keyframes rcSpin { to { transform: rotate(360deg); } }
.rc-shake { animation: rcShake .4s var(--acct-ease) both; }
@keyframes rcShake { 0%, 100% { transform: none; } 20% { transform: translateX(-5px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }

@media (max-width: 560px) {
	.rc-act li { flex-wrap: wrap; }
	.rc-act__when { flex-basis: 100%; }
	.rc-panel { padding: 18px 16px 20px; }
	.rc-reveal h3, .rc-keyrow, .rc-expiry, .rc-steps, .rc-reveal__foot { margin-left: 16px; margin-right: 16px; }
	.rc-reveal__warn { padding: 14px 16px; }
	.rc-keyrow { flex-direction: column; }
	.rc-key { font-size: 17px; letter-spacing: 1.5px; }
	.rc-copy .enttec-btn { width: 100%; }
	.rc-reveal__foot { justify-content: stretch; }
	.rc-reveal__foot .enttec-btn { width: 100%; }
	/* Refresh and Generate stack rather than share a 320px line, where the two
	 * labels wrapped to two lines each.
	 *
	 * align-items: stretch on the parent is not enough: the theme's
	 * `.woocommerce-account .woocommerce button` rule (0,3,1) sets
	 * align-self: flex-start on every button, which wins and leaves the two
	 * stacked buttons at ragged content widths. The #enttec-account prefix (1,2,0)
	 * outranks it. Same trap as the empty-state CTA above. */
	.rc-panel__actions { flex-direction: column; align-items: stretch; }
	#enttec-account .rc-panel__actions .enttec-btn { align-self: stretch; width: 100%; }
}

/* House rule: honour reduced motion. Feedback that only exists as movement
 * (the copy confirmation, the un-copied nudge) keeps a non-motion equivalent:
 * the "Copied" pill still swaps in, and the nudge still appears, they just do
 * not animate. */
@media (prefers-reduced-motion: reduce) {
	.rc-enter { animation: none !important; }
	.rc-shake { animation: none !important; }
	.rc-spin { animation-duration: .001ms !important; }
	.rc-table tbody tr { transition: none !important; }
	.rc-activity summary::before { transition: none !important; }
	.rc-confirm { animation: none !important; }
	.filter-dropdown-wrapper.open .dropdown-menu-custom { animation: none !important; }
	/* The refresh spin goes, so the dimmed pointer-disabled button carries the
	 * in-flight state on its own. */
	.rc-refreshing i { animation: none !important; }
	/* Hold a static tint instead of fading it out. The JS still removes the class
	 * on its timer, so the highlight is temporary either way, and the customer
	 * still gets a non-motion answer to "which row is mine". */
	.rc-table tbody tr.is-new { animation: none !important; background: #e3f4fc; }
}
