/* =========================================================================
   End of Time -- design system
   Ported from the Claude Design handoff bundle
   (_ds/end-of-time-design-system-.../tokens/*.css + _ds_bundle.js).

   Hard constraints from the design system readme -- do not violate:
     1. Type scale is exactly 16 / 32 / 48px. No other sizes.
     2. Font smoothing off everywhere.
     3. No bold, no italic. Hierarchy = color, size, uppercase, bars.
     4. border-radius: 0 everywhere.
     5. No blurred shadows. Depth is a hard 2px bevel; press inverts it.
     6. All spacing and line-heights are multiples of 8px.
     7. No transitions, no eases, no fades.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');

/* ---- tokens/colors.css ------------------------------------------------- */
:root {
	--surface-void:    #05060D;
	--surface-deep:    #0C1129;
	--surface-panel:   #17225C;
	--surface-raised:  #2C41A0;
	--surface-inset:   #080B1C;
	--frame:           #B8862F;
	--frame-light:     #EBC46E;
	--frame-dark:      #63431A;
	--text:            #F2F0E6;
	--text-muted:      #8FA0CC;
	--text-highlight:  #FFD24A;
	--text-link:       #FFA83C;
	--bar-crimson:     #6E1B22;
	--bar-verdant:     #24462F;
	--bar-arcane:      #4E2560;
	--status-online:   #5FD177;
	--status-danger:   #C4444A;
	--text-shadow-hard: 1px 1px 0 #000;

	/* typography
	   The tokens file says one pixel family everywhere, but the prototype's own
	   inline <style> (End of Time Website.dc.html:35-48) overrides it and is what
	   Rauu actually looked at:
	       .pixel-text, .pixel-text *              -> Inter, ANTIALIASED
	       .pixel-text .retro-heading, ... *       -> Pixelify Sans 700, pixel-rendered
	   `.retro-heading` appears exactly once in that file: the wordmark. So the
	   pixel face is for the wordmark ONLY; all body/UI text is Inter. Both keep
	   the 1px hard black text-shadow. */
	--font-ui: 'Inter', system-ui, sans-serif;
	--font-pixel: 'ChronoType', 'Pixelify Sans', monospace;
	--text-wordmark: 48px;
	--text-title: 32px;
	--text-body: 16px;
	--lh-wordmark: 56px;
	--lh-title: 40px;
	--lh-body: 24px;

	/* spacing */
	--space-1: 8px;  --space-2: 16px; --space-3: 24px;
	--space-4: 32px; --space-5: 40px; --space-6: 48px; --space-8: 64px;
	--frame-width: 4px;
	--sidebar-width: 224px;

	/* effects */
	--bevel-raised:  inset 2px 2px 0 var(--frame-light), inset -2px -2px 0 var(--frame-dark);
	--bevel-pressed: inset -2px -2px 0 var(--frame-light), inset 2px 2px 0 var(--frame-dark);
	--panel-gradient: linear-gradient(180deg, var(--surface-raised), var(--surface-panel));
}

/* ChronoType is the real face; it is not bundled (no licence in the handoff),
   so Pixelify Sans carries the metrics. Drop ChronoType.woff2 into
   templates/endoftime/fonts/ and it is picked up with no layout change. */
@font-face {
	font-family: 'ChronoType';
	src: local('ChronoType'), url('fonts/ChronoType.woff2') format('woff2');
	font-weight: 400; font-style: normal; font-display: swap;
}

/* ---- tokens/base.css --------------------------------------------------- */
* { box-sizing: border-box; border-radius: 0 !important; }
*, *::before, *::after { transition: none !important; animation-duration: 0s !important; }

html, body {
	margin: 0;
	padding: 0;
	background: var(--surface-void) url('images/starfield.png') repeat;
	background-size: 256px 256px;
	color: var(--text);
	font-family: var(--font-ui);
	font-size: var(--text-body);
	line-height: var(--lh-body);
	font-weight: 400;
	-webkit-font-smoothing: antialiased;
	font-smooth: auto;
	text-rendering: optimizeLegibility;
	text-shadow: var(--text-shadow-hard);
}

/* Constraint 3: nothing is ever bold or italic. MyAAC's page markup is full of
   hardcoded <b> and <strong>; neutralise them at the source rather than
   chasing every template. */
b, strong, th { font-weight: 400 !important; }
i, em { font-style: normal !important; }

a { color: var(--text-link); text-decoration: none; }
a:hover { color: var(--text-highlight); }

h1, h2, h3, h4, h5, h6 {
	font-weight: 400;
	margin: 0 0 var(--space-2);
	color: var(--text-highlight);
	text-transform: uppercase;
}
h1 { font-size: var(--text-title); line-height: var(--lh-title); }
h2, h3, h4, h5, h6 { font-size: var(--text-body); line-height: var(--lh-body); }

img { max-width: 100%; }
hr { border: 0; border-top: 1px solid var(--surface-void); margin: var(--space-2) 0; }
small { font-size: var(--text-body); color: var(--text-muted); }

/* =========================================================================
   Layout shell
   ========================================================================= */
.eot-page {
	min-height: 100vh;
	padding: var(--space-3) var(--space-3) var(--space-8);
}
.eot-shell {
	max-width: 1200px;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.eot-header {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-5);
	border-bottom: var(--frame-width) solid var(--frame);
	padding-bottom: var(--space-2);
}
.eot-header-side {
	flex: 0 0 var(--sidebar-width);
	width: var(--sidebar-width);
	display: flex;
	justify-content: center;
}
/* The trailing header-side is an empty balancer. With it, the wordmark is
   centred on the whole shell (sidebar + content), which put it visibly left of
   the panel below -- its left edge landed exactly on the panel's left edge.
   Dropping it lets the wordmark span the content column, so heading and panel
   share a centre line. The LEADING side stays: it holds the players-online
   counter, and it is what aligns the wordmark with the content in the first
   place. If a right-hand widget is ever added, delete this rule. */
.eot-header > .eot-header-side:last-child:empty {
	display: none;
}
/* The one place the pixel face is used -- the prototype's `.retro-heading`. */
.eot-wordmark {
	flex: 1;
	max-width: 960px;
	display: block;
	font-family: var(--font-pixel);
	font-weight: 700;
	-webkit-font-smoothing: none;
	font-smooth: never;
	text-rendering: geometricPrecision;
	font-size: 56px;
	line-height: 56px;
	color: var(--text-highlight);
	text-transform: uppercase;
	text-align: center;
	/* 8-way hard outline -- no blur, per constraint 5 */
	text-shadow:
		 1px 0 0 #000, -1px  0 0 #000,  0 1px 0 #000,  0 -1px 0 #000,
		 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;
}
.eot-wordmark:hover { color: var(--text-highlight); }

.eot-body {
	display: flex;
	align-items: flex-start;
	justify-content: center;
	gap: var(--space-5);
}
.eot-sidebar {
	flex: 0 0 var(--sidebar-width);
	width: var(--sidebar-width);
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}
.eot-main {
	flex: 1;
	min-width: 0;
	max-width: 960px;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.eot-footer {
	border-top: var(--frame-width) solid var(--frame);
	padding-top: var(--space-2);
	color: var(--text-muted);
	text-align: center;
}

/* =========================================================================
   StatusCounter -- players-online pill
   ========================================================================= */
.eot-status {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	padding: var(--space-1) var(--space-2);
}
.eot-status-count { color: var(--status-online); }
.eot-status-count.is-offline { color: var(--status-danger); }
.eot-status-label { color: var(--text-muted); text-transform: uppercase; }

/* =========================================================================
   Sidebar login box
   ========================================================================= */
.eot-loginbox {
	background: var(--surface-panel);
	border: var(--frame-width) solid var(--frame);
	box-shadow: var(--bevel-raised);
	padding: var(--space-2);
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	align-items: stretch;
}
.eot-loginbox-status { color: var(--text-muted); text-align: center; }
.eot-loginbox-primary { display: flex; justify-content: center; }
.eot-loginbox-alt {
	display: block;
	text-align: center;
	text-transform: uppercase;
	color: var(--text-link);
}

/* =========================================================================
   NavStack
   ========================================================================= */
.eot-nav { line-height: 32px; }
.eot-nav-title {
	background: var(--bar-verdant);
	color: var(--text);
	text-transform: uppercase;
	padding: 0 var(--space-1);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}
.eot-nav-item {
	display: flex;
	align-items: center;
	height: 32px;
	padding: 0 var(--space-1);
	color: var(--text);
	text-decoration: none;
	border-bottom: 1px solid var(--surface-void);
	background: var(--surface-panel);
}
.eot-nav-item:hover { background: var(--surface-raised); color: var(--text-link); }
.eot-nav-item.active { color: var(--text-highlight); }
.eot-nav-item.active::before { content: '> '; white-space: pre; }

/* =========================================================================
   FramedPanel -- the signature motif.
   The title plate sits ON TOP of the panel's top edge, 8px wider each side,
   with brass end-caps. Not a header inside the box.
   ========================================================================= */
.eot-panel { position: relative; margin-top: var(--space-3); }
.eot-panel-plate {
	position: absolute;
	top: -20px; left: -8px; right: -8px;
	height: 32px;
	display: flex;
	align-items: center;
	background: var(--bar-verdant);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	z-index: 2;
}
.eot-panel--crimson .eot-panel-plate { background: var(--bar-crimson); }
.eot-panel--arcane  .eot-panel-plate { background: var(--bar-arcane); }
.eot-panel--raised  .eot-panel-plate { background: var(--surface-raised); }
.eot-panel-cap {
	width: 16px; height: 100%;
	background: var(--frame);
	box-shadow: inset 1px 1px 0 var(--frame-light), inset -1px -1px 0 var(--frame-dark);
	flex-shrink: 0;
}
.eot-panel-title {
	flex: 1;
	text-align: center;
	text-transform: uppercase;
	color: var(--text);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	padding: 0 var(--space-1);
}
.eot-panel-title a { color: var(--text); }
.eot-panel-box {
	position: relative;
	background: var(--panel-gradient);
	border: var(--frame-width) solid var(--frame);
	box-shadow: var(--bevel-raised);
	padding: var(--space-3) var(--space-2) var(--space-2);
	z-index: 1;
}
.eot-panel-inner {
	border: 1px solid var(--surface-void);
	padding: var(--space-2);
	overflow-x: auto;
}

/* =========================================================================
   Section bars (sub-headings inside a panel)
   ========================================================================= */
.eot-bar {
	display: flex;
	align-items: center;
	min-height: 32px;
	padding: 4px var(--space-1);
	background: var(--bar-verdant);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	color: var(--text-highlight);
	text-transform: uppercase;
}
.eot-bar--crimson { background: var(--bar-crimson); }
.eot-bar--arcane  { background: var(--bar-arcane); }
.eot-bar + table, .eot-bar + .eot-boxbody {
	width: 100%;
	background: var(--surface-panel);
	border: 2px solid var(--frame);
	border-top: none;
}
.eot-boxbody { padding: var(--space-2); }

/* =========================================================================
   Tables.
   Two selector families on purpose:
     .eot-table          -- markup this theme writes itself
     generic table rules -- MyAAC's own page markup, which this theme does not
                            override file-by-file. Those pages emit
                            bgcolor="" from config.ini, so the palette lands
                            even without a template override.
   ========================================================================= */
table { border-collapse: collapse; border-spacing: 0; }

.eot-panel-inner table,
.eot-table,
table.myaac-table,
table.Table1, table.Table2, table.Table3, table.Table4, table.Table5 {
	width: 100%;
	color: var(--text);
}

.eot-panel-inner td,
.eot-panel-inner th,
.eot-table td,
.eot-table th {
	padding: var(--space-1);
	border-bottom: 1px solid var(--surface-void);
	text-align: left;
	vertical-align: top;
}

.eot-panel-inner thead td,
.eot-panel-inner thead th,
.eot-table thead td,
.eot-table thead th {
	background: var(--surface-raised);
	color: var(--text-highlight);
	text-transform: uppercase;
	border-bottom: 2px solid var(--frame);
}

/* Zebra. MyAAC writes bgcolor on many rows already; this covers the rest. */
.eot-table tbody tr:nth-child(odd)  { background: var(--surface-inset); }
.eot-table tbody tr:nth-child(even) { background: transparent; }

table.myaac-table > tbody > tr:nth-child(even) { background: var(--surface-panel); }
table.myaac-table > tbody > tr:nth-child(odd)  { background: var(--surface-inset); }
table.myaac-table > thead > tr > td,
table.myaac-table > thead > tr > th,
table.myaac-table > tfoot > tr > td {
	background: var(--surface-raised);
	color: var(--text-highlight) !important;
}

/* MyAAC's tibia.com-era row classes */
.Odd,  tr.Odd  { background: var(--surface-inset) !important; }
.Even, tr.Even { background: var(--surface-panel) !important; }
.LabelV, .LabelH { color: var(--text-muted); }
.white, .white a { color: var(--text-highlight) !important; }

/* Sortable header cells */
.eot-table th[data-sort], .eot-sortable { cursor: pointer; }

/* =========================================================================
   Admin-authored (WYSIWYG) page content -- Rules, Commands, Downloads, ...
   Written in the admin panel's rich-text editor against the old parchment
   theme, so the stored HTML carries border="1", inline `border-width`,
   hardcoded #ffffff text and brown #9e5e3c section fills. Normalise it to the
   design language here rather than asking every page to be re-edited by hand.
   Scoped to table[border] so it only touches editor output, never the tables
   this theme writes itself.
   ========================================================================= */
.eot-panel-inner table[border] { border: 0 !important; width: 100% !important; height: auto !important; }
.eot-panel-inner table[border] col { width: auto !important; }
.eot-panel-inner table[border] td,
.eot-panel-inner table[border] th {
	border: 0 !important;
	border-bottom: 1px solid var(--surface-void) !important;
	text-align: left !important;
	vertical-align: middle;
	height: auto !important;
	width: auto !important;
	padding: var(--space-1) !important;
}

/* Header row -> the design's raised bar with amber uppercase labels. */
.eot-panel-inner table[border] thead td,
.eot-panel-inner table[border] thead th {
	background: var(--surface-raised) !important;
	color: var(--text-highlight) !important;
	text-transform: uppercase;
	border-bottom: 2px solid var(--frame) !important;
}

/* Any body cell the editor gave an explicit background is a section heading
   (the brown #9e5e3c bars in Rules) -- render it as a bar. */
.eot-panel-inner table[border] tbody td[style*="background-color"] {
	background: var(--bar-verdant) !important;
	color: var(--text-highlight) !important;
	text-transform: uppercase;
	border-bottom: 2px solid var(--frame) !important;
	text-align: center !important;
}

/* Zebra, matching the design's row.bg alternation. */
.eot-panel-inner table[border] tbody tr:nth-child(odd)  { background: var(--surface-inset); }
.eot-panel-inner table[border] tbody tr:nth-child(even) { background: transparent; }

/* Marker/first column -- rule letters and command words, amber per the design. */
.eot-panel-inner table[border] tbody td:first-child { color: var(--text-highlight); }

/* Strip hardcoded ink so pasted content cannot fight the palette. */
.eot-panel-inner [style*="color: #ffffff"], .eot-panel-inner [style*="color:#ffffff"],
.eot-panel-inner [style*="color: #fff"],    .eot-panel-inner [style*="color:#fff"],
.eot-panel-inner [style*="color: #000000"], .eot-panel-inner [style*="color:#000000"],
.eot-panel-inner [style*="color: #000"],    .eot-panel-inner [style*="color:#000"],
.eot-panel-inner [style*="color: white"],   .eot-panel-inner [style*="color: black"] {
	color: inherit !important;
}

/* Editor headings inside table cells are body text at this scale -- <h2>/<h4>
   there would otherwise inherit the global uppercase amber block heading. */
.eot-panel-inner table[border] h1, .eot-panel-inner table[border] h2,
.eot-panel-inner table[border] h3, .eot-panel-inner table[border] h4,
.eot-panel-inner table[border] h5, .eot-panel-inner table[border] h6 {
	margin: 0;
	font-size: var(--text-body);
	line-height: var(--lh-body);
	color: inherit;
	text-transform: none;
	font-weight: 400;
}

/* =========================================================================
   Buttons
   ========================================================================= */
.eot-btn,
input[type="submit"], input[type="button"], input[type="reset"], button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-ui);
	font-size: var(--text-body);
	line-height: var(--lh-body);
	text-shadow: var(--text-shadow-hard);
	color: var(--text);
	background: var(--surface-panel);
	border: 2px solid var(--frame);
	padding: 4px var(--space-2);
	box-shadow: var(--bevel-raised);
	cursor: pointer;
	text-transform: uppercase;
	min-height: 40px;
}
.eot-btn:hover,
input[type="submit"]:hover, button:hover { color: var(--text); background: var(--surface-raised); }
/* Constraint 5: press inverts the bevel -- no colour or scale change. */
.eot-btn:active,
input[type="submit"]:active, input[type="button"]:active, button:active {
	box-shadow: var(--bevel-pressed);
}
.eot-btn--primary { background: var(--surface-raised); }
.eot-btn[disabled], button[disabled], input[disabled] {
	background: var(--surface-inset);
	color: var(--text-muted);
	cursor: default;
	opacity: .6;
}

/* =========================================================================
   Form fields
   ========================================================================= */
/* `input:not([type])` matters: several MyAAC forms (the character search box in
   characters.form.html.twig among them) omit the attribute entirely, so it
   defaults to text while `input[type="text"]` never matches -- those fields
   were falling back to Arial. */
.eot-input,
input:not([type]),
input[type="text"], input[type="password"], input[type="email"],
input[type="number"], input[type="search"], textarea, select {
	font-family: var(--font-ui);
	font-size: var(--text-body);
	line-height: var(--lh-body);
	text-shadow: var(--text-shadow-hard);
	background: var(--surface-inset);
	color: var(--text);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	padding: 4px var(--space-1);
	min-height: 40px;
	max-width: 100%;
}
textarea { min-height: 120px; }
input::placeholder, textarea::placeholder { color: var(--text-muted); }
input[type="checkbox"], input[type="radio"] { min-height: 0; box-shadow: none; }
label { color: var(--text-highlight); text-transform: uppercase; }
select option { background: var(--surface-inset); color: var(--text); }

/* =========================================================================
   News items (crimson header bar + panel body)
   ========================================================================= */
.eot-news { margin-bottom: var(--space-2); }
.eot-news-head {
	display: flex;
	align-items: center;
	min-height: 32px;
	padding: 0 var(--space-1);
	gap: var(--space-1);
	background: var(--bar-crimson);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}
.eot-news-date, .eot-news-author { color: var(--text-muted); flex-shrink: 0; }
.eot-news-title {
	flex: 1; min-width: 0;
	text-align: center;
	color: var(--text-highlight);
	text-transform: uppercase;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.eot-news-body {
	background: var(--surface-panel);
	border: 2px solid var(--frame);
	border-top: none;
	padding: var(--space-2);
}

/* =========================================================================
   Inset card (downloads rows, coin packs, discord link)
   ========================================================================= */
.eot-card {
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	padding: var(--space-2);
}
.eot-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.eot-stack   { display: flex; flex-direction: column; gap: var(--space-3); }
.eot-stack-2 { display: flex; flex-direction: column; gap: var(--space-2); }
.eot-row     { display: flex; gap: var(--space-2); align-items: center; }

/* Optional artwork under the Welcome text (index.php).
   It is a flex item in .eot-stack, so it lays out as its own row already --
   no float, which would have been ignored on a flex item anyway.

   NO fixed width on purpose. The image renders at its native pixel size and
   only shrinks if the panel is narrower than it is. 7.4 sprites are pixel art:
   scaled up they blur, scaled down they lose whole pixel rows, and either way
   they stop reading as a game screenshot. Native or nothing. */
.eot-welcome-art {
	display: block;
	margin: var(--space-1) auto 0;
	max-width: 100%;
	height: auto;
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	/* If it ever DOES have to shrink, keep the pixels hard rather than smeared. */
	image-rendering: pixelated;
}

.eot-muted   { color: var(--text-muted); }
.eot-hl      { color: var(--text-highlight); }
.eot-online  { color: var(--status-online); }
.eot-danger  { color: var(--status-danger); }

/* =========================================================================
   Highscores filter tabs
   ========================================================================= */
.eot-tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.eot-tab {
	padding: 4px var(--space-2);
	cursor: pointer;
	text-transform: uppercase;
	background: var(--surface-panel);
	color: var(--text);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}
.eot-tab:hover { background: var(--surface-raised); color: var(--text-link); }
.eot-tab.active { background: var(--surface-raised); color: var(--text-highlight); }

/* =========================================================================
   Equipment grid -- the classic Tibia inventory arrangement:
       Amu   Helm  Bag
       Weap  Armor Shld
       Ring  Legs  Ammo
       .     Boots .
   ========================================================================= */
.eot-eq {
	display: grid;
	grid-template-columns: repeat(3, 56px);
	gap: var(--space-1);
	justify-content: center;
}
.eot-eq-slot {
	height: 56px;
	background: var(--surface-inset);
	border: 2px solid var(--frame-dark);
	box-shadow: var(--bevel-raised);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--text-muted);
	line-height: 16px;
	text-align: center;
	position: relative;
}
.eot-eq-slot.is-empty { color: var(--text-muted); }
.eot-eq-slot img {
	image-rendering: pixelated;
	max-width: 32px;
	max-height: 32px;
}
.eot-eq-count {
	position: absolute;
	right: 2px; bottom: 0;
	color: var(--text-highlight);
	line-height: 16px;
	text-shadow: var(--text-shadow-hard);
}
.eot-eq-spacer { height: 56px; }

/* Restyle MyAAC's OWN equipment markup (system/templates/characters.html.twig,
   the block between <!-- EQUIPMENT --> and <!-- EQUIPMENT_END -->) into the
   design's slot grid.

   No template override is needed: that markup is already three columns in the
   classic Tibia arrangement -- col1 = necklace/left-hand/ring, col2 =
   head/armor/legs/boots, col3 = backpack/right-hand/ammo -- which is exactly
   the design's layout. Only the skin differs.

   These selectors match the core template's inline styles (#808080 chrome,
   #292929 slot background), so they are coupled to that file. If a MyAAC
   upgrade restyles the equipment block, re-check this rule. !important is
   required because the colours are inline attributes. */
/* Deliberately NOT scoped to .eot-panel-inner: the characters page mixes
   framed sections (which come from tables.headline) with unframed ones, so
   the equipment block is not always inside a panel. */
table[style*="#808080"] {
	background: transparent !important;
	border: 0 !important;
	border-spacing: 8px !important;
	width: auto !important;
}
table[style*="#292929"] {
	background: transparent !important;
	border-spacing: 0 8px !important;
}
td[style*="1px solid #808080"] {
	width: 56px;
	height: 56px;
	padding: 0 !important;
	background: var(--surface-inset) !important;
	border: 2px solid var(--frame-dark) !important;
	box-shadow: var(--bevel-raised);
	text-align: center;
	vertical-align: middle;
}
td[style*="1px solid #808080"] img {
	image-rendering: pixelated;
	vertical-align: middle;
}

/* Outfit portrait on the character page.
   system/templates/characters.html.twig:20 wraps it in a 64x64 circle pinned at
   `margin-left:376px` and force-stretches the <img> to 128x128 with -60px
   margins -- geometry hand-tuned for tibiacom's fixed-width column. Under this
   theme that produced a white square (border-radius:0 squares the circle) with
   a smeared 35x128 sliver of the sprite inside it.

   The outfit service returns a clean 64x64 PNG, so undo the whole hack and show
   it at native size, pixel-rendered, in an inset frame. The div sits directly
   inside <table> before the first <tr>, so browsers hoist it out -- static
   positioning lands it just above the panel. */
div[style*="border-radius:50px"],
div:has(> img[alt="player outfit"]) {
	position: static !important;
	margin: 0 0 var(--space-2) 0 !important;
	padding: 0 !important;
	width: auto !important;
	height: auto !important;
	border: 0 !important;
	display: inline-block;
	line-height: 0;
}
/* `position: static` is the important one. Both the character page and the
   Who-Is-Online list ship the outfit as an absolutely-positioned <img> with
   large negative margins (online.html.twig:172 uses -48px/-70px), geometry
   tuned for tibiacom's fixed column widths. Left alone it floats out of its
   cell and lands on top of the Name column -- which is why the online list
   showed player names with their first letters covered. */
/* outfit.php renders at a native 64x64. Only integer multiples of that are
   used (64 / 128) -- pixelated upscaling at 1.5x gives unevenly sized pixels
   and the sprite looks mushy, which defeats the point of the retro art. */
/* DEFAULT is the list size (64px, native 1:1).
   Previously this defaulted to the 128px portrait and relied on a
   `.eot-panel-inner td > img` rule to shrink it back for lists -- but whether
   the outfit ends up inside .eot-panel-inner depends on whether the page
   happens to be auto-wrapped in a panel, so on Who Is Online the 128px rule
   kept winning and the rows were enormous. Defaulting small and opting IN to
   the big portrait via an explicit class is deterministic. */
img[alt="player outfit"] {
	position: static !important;
	width: 64px !important;
	height: 64px !important;
	max-width: none !important;
	margin: 0 !important;
	object-fit: contain;
	image-rendering: pixelated;
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}

/* Character-page portrait: 2x native, opt-in via the wrapper class. */
.eot-portrait img[alt="player outfit"] {
	width: 128px !important;
	height: 128px !important;
}

/* In the online list the outfit is one cell of a long table, so it stays at
   native 1x -- 128px rows would turn the list into a photo gallery. */
/* Descendant selector, not direct-child: the outfit is sometimes wrapped
   (a link, a span) depending on the page, and when the `>` failed to match,
   the 128px portrait rule above won instead -- which is why the Who Is Online
   list rendered giant outfits and 128px-tall rows. */
.eot-panel-inner td img[alt="player outfit"] {
	width: 64px !important;
	height: 64px !important;
	max-width: none !important;
	object-fit: contain;
}

/* The highscores outfit is built in PHP (system/pages/highscores.php:252) with
   alt="" rather than alt="player outfit", so the rule above never matched it.
   It kept `position:absolute;margin-top:-50px` and floated a row upwards --
   which is why rank 1's outfit sat in the header and every row displayed the
   NEXT player's. Match any absolutely-positioned image inside a table cell
   rather than relying on alt text that differs per page. */
.eot-panel-inner td > img[style*="position:absolute"],
.eot-panel-inner td > img[style*="position: absolute"] {
	position: static !important;
	margin: 0 !important;
	width: 64px !important;
	height: 64px !important;
	/* The global `img { max-width: 100% }` otherwise shrinks these to the
	   cell's content width (59px), squashing the sprite off its pixel grid. */
	max-width: none !important;
	object-fit: contain;
	image-rendering: pixelated;
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}

/* Tabs sit on the panel gradient, which is too close to their own background
   to read as controls. Darken the inactive state so the selected tab stands
   out, matching the reference render. */
.eot-tab { background: var(--surface-inset); }
.eot-tab:hover { background: var(--surface-panel); color: var(--text-link); }
.eot-tab.active { background: var(--surface-raised); color: var(--text-highlight); }

/* =========================================================================
   Message / status blocks
   ========================================================================= */
.eot-msg, .success, .error, .warning, .note {
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	padding: var(--space-1) var(--space-2);
	color: var(--text);
}
.success, .eot-msg--ok  { border-color: var(--status-online); color: var(--status-online); }
.error,   .eot-msg--err { border-color: var(--status-danger); color: var(--status-danger); }
.warning, .note         { border-color: var(--frame); color: var(--text-highlight); }

/* =========================================================================
   Time Coins packs (system/pages/timecoins.php)

   Two columns, matching the handoff prototype's
   `grid-template-columns: repeat(2, minmax(0, 1fr))`. auto-fit rather than a
   hard 2 so the cards go single-column on a phone instead of overflowing.
   ========================================================================= */
/* Exactly 2 across, like the prototype -- auto-fit was fitting three on a wide
   screen and leaving one stranded on its own row. Single column only when the
   cards would genuinely be too narrow. */
.eot-packs {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-2);
}
@media (max-width: 520px) {
	.eot-packs { grid-template-columns: 1fr; }
}
.eot-pack {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-1);
	padding: var(--space-2);
	background: var(--surface-inset);
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
	text-align: center;
}
.eot-pack-coins {
	font-size: 32px;
	line-height: 40px;
	color: var(--text-highlight);
}
.eot-pack-label {
	color: var(--text-muted);
	text-transform: uppercase;
	white-space: nowrap;
}
/* Reserves the row even when a pack has no bonus, so all four Select buttons
   line up instead of the first card riding 24px higher than the rest. */
.eot-pack-bonus {
	color: var(--status-online);
	min-height: 24px;
	white-space: nowrap;
}
.eot-pack-btn {
	margin-top: auto;
	width: 100%;
	text-align: center;
	text-decoration: none;
}
.eot-shopshot {
	display: block;
	width: 400px;
	max-width: 100%;
	/* This is a screenshot of the client, not pixel art scaled up -- leave it
	   to the browser's smooth scaler rather than the global `pixelated`. */
	image-rendering: auto;
	border: 2px solid var(--frame);
	box-shadow: var(--bevel-raised);
}

/* =========================================================================
   Responsive -- the design is a fixed 1200px desktop layout; below that the
   sidebar stacks above the content rather than squeezing the tables.
   ========================================================================= */
@media (max-width: 980px) {
	.eot-body { flex-direction: column; align-items: stretch; }
	.eot-sidebar { flex: 1 1 auto; width: 100%; }
	.eot-header { flex-direction: column; gap: var(--space-2); }
	.eot-header-side { flex: 0 0 auto; width: auto; }
	.eot-wordmark { font-size: var(--text-title); line-height: var(--lh-title); }
	.eot-page { padding: var(--space-2) var(--space-2) var(--space-5); }
}
