/* ============================================================================
   SITE — components. Composed only from tokens.css; no raw colour, size or
   duration appears below this line. If a value is missing, it belongs in the
   token layer, not here.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

html {
	/* Anchors land below the fixed bar instead of underneath it. */
	scroll-padding-top: calc(var(--bar-h) + var(--s-4));
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	/* THE PAGE IS A COLUMN THAT REACHES THE FLOOR, so the footer is at the
	   bottom of the window on a short page and after the content on a long
	   one. Without this the 404, the "we sent the letter" endings and an empty
	   ranking left the footer hanging in the middle of the screen with the
	   body's own ground below it.
	   Only two of body's children are in the flow -- <main> and <footer>. The
	   announcement strip, the masthead and the Greek-key rule under it are all
	   position:fixed, so they are not flex items and cost the column nothing.
	   svh rather than vh: on a phone vh is measured against the browser's
	   toolbar-collapsed height, which would make the column taller than the
	   screen and put a scrollbar on every short page. */
	min-height: 100svh;
	display: flex;
	flex-direction: column;
	background: var(--c-ground);
	color: var(--c-ink);
	font-family: var(--f-text);
	font-size: var(--step-0);
	font-weight: var(--w-regular);
	line-height: var(--lh-body);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* <main> IS THE PART THAT STRETCHES. It takes whatever height the window has
   left over after the footer, which is what holds the footer on the floor.
   flex-shrink 0 so a page taller than the window is never squeezed into it.

   AND IT IS A COLUMN ITSELF, so the slack can be handed on. Left as a plain
   block, a stretched <main> on a short page would be a 400px band of the
   message screen's own plate with the body's darker ground showing between it
   and the footer -- a seam across the window, which is the exact fault the
   message band used to answer by asking for the whole screen. Passing the
   slack to the page's LAST band instead means the band that ends the page is
   the thing that reaches the footer, whichever page it is: every template's
   content block ends in a full-width section. */
main {
	flex: 1 0 auto;
	display: flex;
	flex-direction: column;
}
main > :last-child { flex-grow: 1; }

h1, h2, h3 {
	font-family: var(--f-display);
	/* 600 for the two lower ranks and 700 for h1, which is the atlas's split:
	   in a condensed face the step between 600 and 700 is most of what tells
	   a page title apart from a section title, since neither can lean on
	   width to do it. */
	font-weight: var(--w-semibold);
	line-height: var(--lh-heading);
	letter-spacing: var(--ls-tight);
	margin: 0;
	text-wrap: balance;
}
h1 { font-weight: var(--w-bold); }

p { margin: 0; max-width: var(--measure); }

/* EVERY SMALL ALL-CAPS LABEL IS SET IN THE DISPLAY FACE, and they are listed
   together rather than repeating two declarations twenty times. This is the
   atlas's own division of labour: an eyebrow, a column head, a chip and a
   form label are signage, not prose, and Oswald at 500 is what the atlas
   signs with. Declared here, near the top, so the rules further down that own
   these selectors keep their size, colour and spacing and inherit only the
   face -- adding a family line to each of them would be the same change made
   twenty times and wrong in one of them.

   Medium, not semibold: at this size with .13em of tracking the heavier
   weight fills its own counters and the word turns into a bar. */
/* THE LIVE COUNT IN THE BAR. Quiet on purpose: it sits beside the brand and
   must not compete with the two buttons on the other side. The dot is what
   makes the number mean "now" rather than "in total". */

.live-chip {
	margin-inline-end: auto;
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	font-size: var(--step--1);
	color: var(--c-ink-dim);
	white-space: nowrap;
}
.live-chip b { color: var(--c-ink); font-weight: var(--w-semibold); }
.live-dot {
	inline-size: .5rem;
	block-size: .5rem;
	border-radius: 50%;
	background: var(--c-ok);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-ok) 22%, transparent);
	flex: none;
}
/* Below the breakpoint the bar has the brand, the chip and the burger to fit;
   the count is the one of the three nobody came for. */
@media (max-width: 60rem) { .live-chip { display: none; } }

.tiles dt,
.field > span,
.maint-note h2,
table.rank th,
table.spec th,
.ann .tag {
	font-family: var(--f-display);
	font-weight: var(--w-medium);
}

a { color: var(--c-gold-soft); text-decoration: none; }
a:hover { color: var(--c-gold-hi); }

:focus-visible {
	outline: 2px solid var(--c-gold);
	outline-offset: 3px;
	border-radius: var(--r-sm);
}

img { max-width: 100%; display: block; }

.wrap {
	width: 100%;
	max-width: var(--w-page);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* Visible to a screen reader, not to the eye. Used for the skip link and for
   labels that the layout communicates visually but the markup must still say. */
.sr {
	position: absolute; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden;
	clip-path: inset(50%); white-space: nowrap;
}
.skip:focus {
	position: fixed; inset-block-start: var(--s-3); inset-inline-start: var(--s-3);
	width: auto; height: auto; clip-path: none; z-index: 100;
	background: var(--c-gold); color: var(--c-gold-ink);
	padding: var(--s-3) var(--s-4); border-radius: var(--r);
}

/* ---- BAR ---------------------------------------------------------------- */

/* THE WORDMARK HANGS BELOW THE BAR, and the two rules that do it are these.
   The bar's height is --h-bar and nothing inside it can change that, so making
   the logo taller than the bar makes it overhang rather than making the bar
   grow -- the page below does not move.

   THE HEIGHT IS A MULTIPLE OF --h-bar, NOT A PIXEL COUNT. --h-bar is itself a
   clamp that runs from 3.5rem on a phone to 4.5rem on a wide screen; a fixed
   112px would be a tasteful overhang on the desktop and nearly double the bar
   on a phone. Tying them together keeps the proportion the same everywhere,
   which is the thing that was chosen. */
.brand {
	display: flex;
	align-items: center;
	/* Above the bar's own background and below nothing: the overhanging part
	   has to sit over the page, and the bar is already at z-index 50. */
	position: relative;
	z-index: 1;
}
.brand img {
	display: block;
	block-size: calc(var(--h-bar) * 1.55);
	inline-size: auto;
	/* The overhang must not make the bar wider than the viewport on a small
	   screen; the logo shrinks before that happens. */
	max-inline-size: 52vw;
	object-fit: contain;
}
/* A picture cannot take the hover colour a word could, so the cue is light.
   Kept small on purpose: the mark is the loudest thing in the bar already. */
.brand:hover img { filter: brightness(1.08); }

/* The signed-in visitor's own numbers. Only the ones the site can read: see
   render.PlayerSummary for why rank and EP are not among them. */
.tiles {
	/* Row gap to the atlas's .live (1.7rem); the column gap is the site's own
	   and is left where it was. */
	display: flex; flex-wrap: wrap; gap: var(--s-5) var(--s-6);
	margin: 0;
}
.tiles .tile { display: grid; gap: var(--s-1); }
.tiles dt {
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	color: var(--c-ink-faint);
}
/* A NUMBER A PLAYER COMPARES AGAINST ANOTHER NUMBER IS SET IN THE MONO FACE.
   The atlas draws every level, rank, balance and countdown in IBM Plex Mono
   and it is not decoration: the figures are the same width, so two rows of a
   ranking line up down the column and "1.240" and "980" can be told apart at
   a glance instead of read. Headings stay in the display face -- a step
   number or a 404 is a mark, not a quantity. */
.tiles dd {
	margin: 0;
	font-family: var(--f-mono);
	font-size: var(--step-2);
	line-height: var(--lh-tight);
	color: var(--c-ink);
	font-variant-numeric: tabular-nums;
}
.card h3 {
	text-transform: uppercase;
	letter-spacing: var(--ls-head);
}

/* ---- GRID / CARD -------------------------------------------------------- */

.card {
	background: var(--c-panel);
	border: var(--bw) solid var(--c-line);
	border-radius: var(--r);
	/* The atlas pads its boxes .85rem to 1rem in the block direction. Only the
	   block direction changes here -- the inline padding is the site's. */
	padding: var(--s-4) var(--s-5);
	transition: border-color var(--t) var(--ease), transform var(--t) var(--ease),
	            box-shadow var(--t) var(--ease);
}
.card:hover {
	border-color: var(--c-gold-dim);
	transform: translateY(-2px);
	box-shadow: var(--sh-1);
}
.card h3 { font-size: var(--step-2); margin-block-end: var(--s-1); }
.card p { color: var(--c-ink-dim); font-size: var(--step--1); }

/* Tabs without script: a radio per panel, hidden, and sibling selectors do
   the switching. The inputs stay focusable so the keyboard still drives it. */
.tab-in { position: absolute; opacity: 0; pointer-events: none; }
/* atlas .tabs: .9rem under the row, whether it is a card's two halves or the
   ranking's filters. */
.tabs { display: flex; gap: var(--s-1); margin-block-end: var(--s-4); }
.tab {
	flex: 1 1 auto;
	text-align: center;
	cursor: pointer;
	/* A tab is a sign, like the column heads above: display face, small,
	   upper case. The atlas tracks it narrower than an eyebrow because a tab
	   has a box around it and the tracking would push the word into it. */
	font-family: var(--f-display);
	font-size: var(--step--1);
	font-weight: var(--w-medium);
	text-transform: uppercase;
	letter-spacing: var(--ls-tab);
	color: var(--c-ink-dim);
	padding: var(--s-2) var(--s-4);  /* atlas .tab: .45rem                  */
	border: var(--bw) solid var(--c-line);
	border-radius: var(--r);
	transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease),
	            border-color var(--t-fast) var(--ease);
}
a.tab { text-decoration: none; }

/* THE CARD CHANGES HEIGHT, THE PAGE DOES NOT. The register form is taller
   than the sign-in one, and it used to push the section -- and everything in
   it -- downwards. Two things fixed that and both are needed: the section is
   pinned to the screen height (see .hero), and the register form was made
   short enough to fit inside it. Reserving the taller form's height under the
   shorter one was tried first and rejected: it left a third of the card empty
   in the view most people see. */
.tab-body { display: none; }

#rank-players:checked ~ .tabs [for="rank-players"],
#rank-guilds:checked  ~ .tabs [for="rank-guilds"] {
	/* Solid gold, not the dim olive it used to be. Over a photograph the olive
	   read as a disabled tab: the selected one has to be the brightest thing in
	   the card, or nobody can tell which half of the form they are looking at. */
	background: var(--c-gold);
	border-color: var(--c-gold);
	color: var(--c-gold-ink);
}
#rank-players:checked ~ .tab-body[data-for="players"],
#rank-guilds:checked  ~ .tab-body[data-for="guilds"] { display: block; }

/* Keyboard focus has to be visible even though the input itself is not. */
.tab-in:focus-visible ~ .tabs .tab { outline: 2px solid var(--c-gold); outline-offset: 2px; }

/* ---- FORM --------------------------------------------------------------- */

/* atlas .f: .85rem between one field and the next. */
.form { display: grid; gap: var(--s-3); }
/* align-content, and it is what keeps a pair of fields on one row the same
   shape. Two .field boxes side by side stretch to the height of the taller
   one, and a stretched grid stretches its ROWS -- so the box next to a field
   carrying a sentence under it grew into a rectangle twice the height with its
   label floating away from it. Packing the rows to the top means a hint under
   one of a pair changes what is below the pair, not the pair. */
.field { display: grid; gap: var(--s-1); align-content: start; }  /* atlas .f label: .28rem */

.field > span {
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	color: var(--c-ink-faint);
}
.field input {
	font: inherit;
	font-size: var(--step-0);
	color: var(--c-ink);
	background: var(--c-well);
	border: var(--bw) solid var(--c-line);
	border-radius: var(--r);
	/* atlas .f .in: .55rem. With the site's line height that is a 44px box,
	   so the field is still a finger's target at the atlas's measure. */
	padding: var(--s-2) var(--s-4);
	width: 100%;
}
.field input::placeholder { color: var(--c-ink-faint); }
.field input:focus-visible { border-color: var(--c-gold-dim); }
/* The red border, and WHEN it may appear.
   It was `:invalid:not(:placeholder-shown)`, and the guard only works on a
   field that has a placeholder: the account box has one, the password boxes do
   not, so every untouched password rendered red before anyone typed a
   character -- the form opened looking like it had already been failed. The
   deletion-code field would have joined it.
   `:user-invalid` is the selector that means what the guard was reaching for:
   invalid AND the person has interacted with it. A browser too old to know it
   shows no red at all, which loses a hint but never accuses anyone of an error
   they have not made yet. */
.field input:user-invalid { border-color: var(--c-danger); }
.field small { font-size: var(--step--2); color: var(--c-ink-faint); }

.field-note { font-size: var(--step--2); color: var(--c-ink-faint); }

.linky { color: var(--c-gold-soft); cursor: pointer; text-decoration: underline; }
/* The portrait. A background on an empty box rather than an <img>, because it
   is decoration: the class is written out in words on the very next line, so a
   picture of it carries nothing a screen reader needs and any alt text would be
   an invention. It keeps the well ground underneath, which is what an unmatched
   class is left showing. */
.ch-ic {
	inline-size: var(--sz-portrait);
	block-size: var(--sz-portrait);
	flex: 0 0 auto;
	border: var(--bw) solid var(--c-line-hi);
	background-color: var(--c-well);
	background-size: cover;
	background-position: var(--pos-portrait);
}
/* THE FOUR CLASSES, KEYED OFF THE GAME'S JOB BYTE, not off the printed name --
   see render.Character.ClassSlug. A character whose job byte is outside the
   game's table matches none of these: it keeps the empty square and the meta
   line's ordinary ink, which is the honest answer. A default face would tell a
   player their character is a class it is not.
   The paintings are the ones the sign-in and class sections already use, so the
   face on the card is the face on the poster. */
.ch-warrior  .ch-ic { background-image: url("/assets/img/class-warrior-face.fff66f81.webp"); }
.ch-assassin .ch-ic { background-image: url("/assets/img/class-assassin-face.738b4a68.webp"); }
.ch-sura     .ch-ic { background-image: url("/assets/img/class-sura-face.a2347a6a.webp"); }
.ch-shaman   .ch-ic { background-image: url("/assets/img/class-shaman-face.fa4fe799.webp"); }
/* The class colours the atlas gives the four classes. Set as a custom property
   on the card rather than as a colour on the word, so the card is the one place
   that knows which class it is.

   THESE FOUR RULES ARE THE SITE'S ONLY CLASS-TO-COLOUR TABLE, and the ranking
   reaches for them too: a podium card and a row of the landing page's preview
   carry the same ch-<slug> and get the same four colours out of it. A second
   table under a ranking-flavoured name would be the same decision written
   twice, and the copy that is wrong is the one nobody is looking at.

   THE SLUG IS THE JOB BYTE, NOT THE CLASS WORD. Every template writes it with
   {{classSlug .Job}} (gamename.ClassSlug), so a corrected Turkish class name
   cannot repaint the ranking, and a job number the site does not know produces
   no class at all -- the word then keeps the ordinary ink through the fallback
   in --c-class's var(), which is the honest answer. */
.ch-warrior  { --c-class: var(--c-class-warrior); }
.ch-assassin { --c-class: var(--c-class-ninja); }
.ch-sura     { --c-class: var(--c-class-sura); }
.ch-shaman   { --c-class: var(--c-class-shaman); }

.ch-who { display: grid; gap: 2px; min-width: 0; }
/* Player-chosen text, so it can be anything: it wraps rather than stretching
   the box or escaping it. */
.ch-name {
	font-family: var(--f-display);
	font-weight: var(--w-medium);
	font-size: var(--step-0);
	line-height: var(--lh-heading);
	color: var(--c-ink);
	overflow-wrap: anywhere;
}
.ch-meta {
	font-size: var(--step--2);
	color: var(--c-ink-faint);
	overflow-wrap: anywhere;
}
/* The class word, in the class's own colour. <em> in the markup because it is
   the one distinguishing word in the line; the italic it would otherwise get is
   turned off, since the colour and the caps are doing that work. The fallback
   is the ordinary meta ink, which is what an unmatched class keeps. */
.ch-class {
	font-style: normal;
	text-transform: uppercase;
	letter-spacing: var(--ls-class);
	color: var(--c-class, var(--c-ink-faint));
}
.ch-lvl {
	margin-inline-start: auto;
	font-size: var(--step--1);
	color: var(--c-gold-soft);
	white-space: nowrap;
}

/* The order table borrows the ranking's table, which already handles a narrow
   column by scrolling inside .table-scroll. Only the product column differs:
   it is prose and must wrap instead of widening the table. */
.orders td:nth-child(2) { overflow-wrap: anywhere; white-space: normal; }
/* THREE TONES, NOT SIX. The six order statuses are grouped into the three
   answers a player is after -- it arrived, it is on its way, it did not happen
   -- and the colours carry the group while the word beside them carries the
   detail. Six colours would hide the one row that went wrong as thoroughly as
   none would. The three are the site's existing meanings and no fourth was
   invented: jade for finished, the soft gold the account's own status row uses
   for not-settled-yet, and the red every refused form is set in. A status the
   site cannot classify carries no class here and keeps the table's ink.
   Scoped under .orders td for the same reason .kv-ok is scoped: the table's own
   `td` rule is an element inside a class and would otherwise win. */
.orders td.orders-ok   { color: var(--c-ok); }
.orders td.orders-wait { color: var(--c-gold-soft); }
.orders td.orders-bad  { color: var(--c-danger-ink); }
/* ---- LIVE BAND ---------------------------------------------------------- */

/* ---- NEWS --------------------------------------------------------------- */
#news-all:checked        ~ .tabs [for="news-all"],
#news-duyuru:checked     ~ .tabs [for="news-duyuru"],
#news-guncelleme:checked ~ .tabs [for="news-guncelleme"],
#news-etkinlik:checked   ~ .tabs [for="news-etkinlik"] {
	background: var(--c-gold-deep);
	border-color: var(--c-gold-dim);
	color: var(--c-gold-soft);
}

.news { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.tag-duyuru     { background: var(--c-gold-tint); color: var(--c-gold-soft); }
.tag-guncelleme { background: rgba(94,155,110,.12); color: var(--c-ok); }
.tag-etkinlik   { background: rgba(178,86,79,.14); color: var(--c-danger-ink); }
table.rank {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--step-0);
	min-width: 40rem;
	/* A PANEL, NOT A BARE TABLE. The atlas draws .rank on the card ground with
	   a hairline around it, the same box the podium above it stands in -- and
	   ours had neither, so the table floated on the page while every other
	   block on the screen sat in something. Measured against the atlas at
	   1246px: theirs background #1C1510 + 1px #3A2A1E, ours transparent and
	   border 0. */
	background: var(--c-panel);
	border: var(--bw) solid var(--c-line);
}
table.rank th {
	text-align: start;
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	color: var(--c-ink-faint);
	padding: var(--s-2) var(--s-4);   /* atlas .rank th: .45rem             */
	border-block-end: var(--bw) solid var(--c-line);
	white-space: nowrap;
}
table.rank td {
	padding: var(--s-2) var(--s-4);   /* atlas .rank td: .42rem             */
	border-block-end: var(--bw) solid var(--c-hair);
	color: var(--c-ink-dim);
}
/* The name is the one column a person is scanning for, so it carries the
   page's full ink and a heavier weight than the facts around it -- atlas
   .rank td.n. */
table.rank td:nth-child(2) { color: var(--c-ink); font-weight: var(--w-semibold); }
table.rank .num { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
/* A QUANTITY IS RIGHT-ALIGNED AND GOLD, and both halves of that are the
   ranking's, not every table's: the place, the level and the score are three
   columns of figures read DOWN rather than across, and ragged-left figures in
   the mono face defeat the point of setting them in it. Gold because they are
   the numbers the page exists to show; the guild beside them is context.
   :not(.orders) because the account page's purchase table borrows .rank for
   its shape only -- the atlas draws that one as its own .ord, with no gold and
   no column of places, and a right-aligned gold EP figure there would make a
   receipt look like a leaderboard. */
table.rank:not(.orders) .num { text-align: end; color: var(--c-gold-hi); }
table.rank tbody tr { transition: background var(--t-fast) var(--ease); }
table.rank tbody tr:hover { background: var(--c-gold-tint); }
/* THE VISITOR'S OWN ROW. The wash is the atlas's .rank tr.me; the gold edge
   and the word beside the name are what keep the mark legible on a screen
   where the wash cannot be seen -- and the edge is reserved as transparent on
   every other row so that marking one does not shift the column under it.
   Declared after :hover so that a row which is mine stays marked while the
   pointer is over it. */
table.rank tbody tr.rank-mine { background: var(--c-mine-tint); }
table.rank:not(.orders) tbody tr td:first-child {
	border-inline-start: var(--bw-mark) solid transparent;
}
table.rank tbody tr.rank-mine td:first-child { border-inline-start-color: var(--c-gold); }  /* atlas .ord td: .42rem */

/* ---- DISCORD ------------------------------------------------------------
   The gold-bordered "the community lives on Discord" block used to stand here
   and the download page was its only caller. The atlas draws that offer as an
   ordinary box in the page's right-hand column instead -- see .dl-box -- so a
   second, louder box competing with the page's one gold button is gone, and
   the rules that drew it went with it. */

/* ---- MENU (disclosure, no script) --------------------------------------
   Wide: the panel is always open and the toggle is gone, so <details> costs
   nothing on desktop. Narrow: it becomes a drop panel under the bar.

   <details> rather than a hidden checkbox: the browser already gives it a
   toggle role, keyboard operation and an open/closed state a screen reader can
   announce, all of which the checkbox trick has to fake. And the launch page
   ships no JavaScript -- a menu that needs a script is a menu that fails while
   the script is still in flight, on exactly the connections where it matters.*/

.menu { margin-inline-start: auto; }
/* THE WHOLE DESKTOP NAVIGATION DEPENDS ON THIS ONE LINE. A closed <details>
   now hides its contents through ::details-content { content-visibility:
   hidden } in the user-agent sheet (Chrome 131+,
and the rest are following),
where the disclosure is deliberately left closed and
   its toggle removed,
every link in the masthead rendered into nothing.
   Measured in Chrome 152: brand and beta chip visible,
nav gone.
   Browsers that do not know the pseudo-element drop the rule and were never
   affected in the first place. */
.menu::details-content { content-visibility: visible; }
.menu > summary { display: none; }

/* The account name and its badge are one link. Padding rather than bare text
   so the target is a target: the pair used to be two spans beside a button and
   the words themselves did nothing. */
.who-link {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	padding: var(--s-1) var(--s-2);
	border-radius: var(--r-sm);
	text-decoration: none;
	color: inherit;
}
.who-link:hover { background: var(--c-raise); }
.who-link:hover .who { color: var(--c-ink); }
.who { font-size: var(--step--1); color: var(--c-ink-dim); }
/* The initial beside the name. A circle rather than an avatar because there is
   no picture to show and there never will be -- the game has no profile image
   -- and a grey silhouette would be a promise of one. Fixed size in both
   directions so a wide letter cannot stretch it into an egg. */
.who-badge {
	flex: none;
	inline-size: 1.75rem;
	block-size: 1.75rem;
	display: inline-grid;
	place-items: center;
	border-radius: 50%;
	border: var(--bw) solid var(--c-gold-dim);
	background: var(--c-ground-2);
	color: var(--c-gold-soft);
	font-size: var(--step--1);
	line-height: 1;
}
.inline { display: inline; margin: 0; }

/* ---- RANKING + NEWS, SIDE BY SIDE ---------------------------------------
   Both halves are previews of pages that already exist, so each carries its
   own link out and neither tries to be the full list. Either half is drawn
   only when its source answered -- see templates/home.html. */

.duo {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
	/* Row gap to the atlas's .two (1.8rem); the column gutter stays. */
	gap: var(--s-6) var(--s-7);
	align-items: start;
}
/* THE RANKING COLUMN IS THE WIDER ONE. The atlas's .two is 1.1fr .9fr, not two
   halves, and the ratio is doing work rather than decorating: the ranking row
   carries a place, a colour, a name, a class, a guild and a level on one line
   and the news entry carries a heading over a sentence that can wrap. Split
   down the middle, the ranking is the column that runs out of room first.
   896px, not the width the auto-fit itself folds at: the two are close enough
   that at the fold the ratio would be deciding the number of columns as well
   as their sizes, and a stated ratio has no fallback to one column.

   EITHER HALF MAY BE ABSENT. The template draws a column only when its own
   source answered, so a failed news read leaves the ranking alone in a grid
   that has been told it has two columns -- and it would sit in 55% of the row
   with the rest of it empty. :only-child is that case, and it takes the whole
   width. */
@media (min-width: 56rem) {
	.duo { grid-template-columns: 1.1fr 0.9fr; }
}
.ch-lvl { font-family: var(--f-mono); }

/* 820px -- the bar's links collapse into the disclosure. */
/* 820px -- THE BAND CHANGES JOB. Above this width it is a backdrop and the
   words sit on its dark left side. Below it there is no dark left side to sit
   on: the section is one column, so the picture becomes a banner across the
   top and the text starts underneath it, on the page's own ground where it is
   always readable. One file at both widths, cropped rather than swapped: the
   picture a visitor sees on a phone must be the one they saw on a desktop. */
@media (max-width: 51.25rem) {
	

	.menu > summary {
		display: block;
		list-style: none;
		cursor: pointer;
		border: var(--bw) solid var(--c-line);
		border-radius: var(--r);
		padding: var(--s-3);
		color: var(--c-ink);
		line-height: 0;
	}
	.menu > summary::-webkit-details-marker { display: none; }
	/* Three rules drawn with borders instead of an icon font or an SVG: fewer
	   bytes, and it inherits the text colour including on focus. */
	.menu > summary > span {
		display: block; width: 1.25rem; height: 2px;
		background: currentColor;
		box-shadow: 0 6px 0 currentColor, 0 -6px 0 currentColor;
	}
	.menu[open] > summary > span { box-shadow: none; transform: rotate(45deg); }
	.menu[open] > summary > span::after {
		content: ""; display: block; width: 1.25rem; height: 2px;
		background: currentColor; transform: rotate(-90deg);
	}
	.duo { gap: var(--s-5); }
}

/* 520px -- one column throughout; the two hero actions become full-width so
   neither is a thumb-stretch on a phone. */
@media (max-width: 32.5rem) {
	.tabs { flex-wrap: wrap; }
	/* The ranking row's phone shape is set further down, with the rest of the
	   phone layout -- see "THE RANKING ROW FOLDS IN TWO". */
	.tiles { gap: var(--s-5); }
}
not the paragraph inside the box -- and the global
   p {max-width:measure} makes that box narrower than the panel {
	margin-block-start: var(--s-2);
	margin-inline: auto;
	max-width: var(--measure);
	font-size: var(--step-1);
	color: var(--c-ink);
}

/* The orders table is not the ranking table, and it should not inherit the
   ranking's 40rem minimum. It has four short columns -- a date, a name, a
   number and a word -- and it lives in the account page's narrower right
   column: at 1920 the box is 536px wide and a 640px minimum meant the last
   column, "Durum", was off the edge at EVERY window width. Measured before:
   box 536 / table 640, 104px hidden, the status column never once visible.
   28rem is what the four columns actually need. */
table.rank.orders { min-width: 28rem; }

/* A two-column requirement/value table. Narrower minimum than table.rank's
   five columns: 40rem would force a scrollbar on a phone for two words a row.

   NOT CALLED .kv, and that is not a style preference: .kv above is the account
   page's definition list and it sets display:grid. A table wearing it turned
   its own head and body into two grid items sitting side by side -- a header
   stranded to the left of the rows it labels. A new class name is one word;
   the debugging was not. */
table.spec {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--step-0);
	/* 18rem, measured rather than picked: at 22rem the box scrolled by a single
	   pixel on a 390px phone, which is a scrollbar and no information. */
	min-width: 18rem;
}
table.spec th {
	text-align: start;
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	color: var(--c-ink-faint);
	padding: var(--s-3) var(--s-4);
	border-block-end: var(--bw) solid var(--c-line);
	white-space: nowrap;
}
table.spec td {
	padding: var(--s-3) var(--s-4);
	border-block-end: var(--bw) solid var(--c-hair);
	color: var(--c-ink-dim);
}
table.spec td:first-child { color: var(--c-ink); }
table.spec tr:last-child td { border-block-end: 0; }

/* ---- ANNOUNCEMENT STRIP -------------------------------------------------
   One line above the masthead, on every page, only when there is something to
   say. The markup is in layout.html and is drawn inside {{if .Ann}}: there is
   no empty state to style, because an empty strip is never rendered.

   HOW IT MAKES ROOM FOR ITSELF, with no JavaScript. tokens.css defines
   --bar-h as (--h-bar + --ann-top) -- the whole pinned masthead, not just the
   bar -- and every clearance on the site is already measured from --bar-h.
   Turning --ann-top on here therefore moves the bar, the ornament rule, the
   main padding, the hero, the anchor offset and the mobile drop panel down by
   exactly the strip's height, in one declaration. The two rules below are the
   only ones that have to know the strip exists at all.

   --ann-top is set on the ROOT element, not on body: custom properties are
   substituted where they are declared, and --bar-h is declared on :root. A
   flag on body would be read too late to change it. */
html.ann-on { --ann-top: var(--h-ann); }

.ann {
	position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 51;
	height: var(--h-ann);
	display: flex; align-items: center;
	/* THE STRIP IS RED, AND IT IS A GRADIENT RATHER THAN A BAR. Dark at both
	   ends and hot in the middle, so that across a 1920 monitor it reads as a
	   banner over the page instead of a solid wall of red -- which is the one
	   thing it must not look like, because a red wall across the top of a
	   site says "the site is broken" and this strip says "read this". */
	background: var(--g-ann);
	border-block-end: var(--bw) solid var(--c-ann-line);
	color: var(--c-ann-ink);
	font-size: var(--step--1);
	/* Above the bar's z-index and above its blur: the strip is opaque, so a
	   backdrop-filter underneath must not pick it up. */
}
.ann > .wrap {
	display: flex; align-items: center; gap: var(--s-3);
	/* The sentence is the part that may be long; it is the part that gets cut,
	   and the tag and the link stay whole. One line, always -- a strip that
	   wraps to two lines is taller than the space the page reserved for it and
	   would slide under the bar. */
	min-width: 0;
}
.ann .tag {
	flex: none;
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	padding: var(--s-1) var(--s-3);
	border-radius: var(--r-sm);
	/* On the strip's own ground, not the page's: the chip is a hole punched
	   in the banner, so it darkens what is behind it rather than picking up
	   the gold wash it would have worn on the dark bar. */
	background: rgba(0,0,0,.28);
	border: var(--bw) solid rgba(255,255,255,.18);
	color: inherit;
	line-height: 1;
}
.ann-text {
	min-width: 0;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
	color: inherit;
}
.ann-more {
	flex: none;
	margin-inline-start: auto;
	color: #fff;
	white-space: nowrap;
	text-decoration: underline;
	text-underline-offset: .2em;
}
.ann-more:hover { color: var(--c-ann-ink); }

/* MAINTENANCE IS THE LOUDER ONE. Same shape, different weight: the tag turns
   red and the sentence comes up to full-strength ink, because a person who is
   about to be disconnected has to read it without deciding to. The strip's
   ground stays dark -- a red bar across the top of the site says "the site is
   broken", which is a different message from "the game is down at nine". */
/* MAINTENANCE IS STILL THE LOUDER ONE, and now that the ordinary strip is
   already red it has to get louder inside the same colour rather than by
   changing to another one. Same gradient, one stop brighter -- the atlas's
   --ember-hi in the middle instead of its mid red -- and the sentence comes
   up to full white. A person who is about to be disconnected has to read it
   without deciding to.

   The jade variant the atlas also draws is NOT used here: with the red strip
   spoken for by the announcement, a green bar for "the server is going down"
   would be the reassuring colour on the alarming message. Its tokens stay
   declared for the day a third kind of notice needs them. */
.ann-maint {
	background: var(--g-ann-maint);
	border-block-end-color: var(--c-ann-maint-line);
}
.ann-maint .ann-text { color: #fff; }

/* THE NARROW-SCREEN DROP PANEL MEASURES FROM THE BAR, NOT FROM THE PAGE.
   It is position:absolute and its containing block is .bar itself (the nearest
   positioned ancestor), so its offset has to be the bar's OWN height. With
   --bar-h now meaning the whole pinned stack, the panel would hang the strip's
   height below the bar and leave a gap of the page showing through. Measured
   at 390x844: 124.8px instead of 90.4px before this rule. */

/* ---- MAINTENANCE HERO ---------------------------------------------------
   The front page while the game is closed. Same section, same painting, same
   height -- only the column layout and what stands in it change, so the page
   does not appear to have been replaced by a different site.

   ONE COLUMN. The second column of the ordinary hero is the sign-in panel, and
   there is nothing to sign in to; leaving the grid at two columns would set
   the whole message in a narrow half with a hole beside it. */

/* What still works, under the buttons. A quiet box rather than another
   headline: it is reassurance, and reassurance shouted is not reassuring. */
.maint-note {
	/* atlas .maint p: 1.3rem before whatever closes the screen. */
	margin-block-start: var(--s-5);
	max-width: var(--measure);
	padding: var(--s-3) var(--s-5);
	background: var(--c-gold-tint);
	border-inline-start: 2px solid var(--c-gold-dim);
	border-radius: var(--r-sm);
}
.maint-note h2 {
	margin: 0 0 var(--s-2);
	font-size: var(--step--2);
	text-transform: uppercase;
	letter-spacing: var(--ls-wide);
	color: var(--c-gold-soft);
}
.maint-note p { margin: 0; font-size: var(--step--1); color: var(--c-ink-dim); }

/* ============================================================================
   THE ATLAS
   ==========================================================================
   The screen atlas (scratchpad/site/sancar2-atlas.html) is the approved
   design, and the site had drifted from its LAYOUT while matching its words.
   This block is the drift, corrected. It sits before the narrow-screen block
   below on purpose: several rules here are about the wide layout only, and the
   phone rules have to be able to win over them at equal specificity, which is
   decided by order.

   WHAT THE ATLAS SAYS ABOUT THE FRONT PAGE, and what the site was doing:
     - one full-width plate with the words on its dark left side; the site had
       cut the plate in half to make room for a sign-in card;
     - a 440px band, not a whole screen;
     - two buttons under the sentence, the download filled and first; the site
       had one;
     - the counters INSIDE the hero as a strip under a gold rule, value over
       label; the site had them below everything, label over value;
     - the four classes introduced by a CENTRED heading; the site left-aligned
       it;
     - sign-in and "open an account" both in the bar; the site had one.
   ========================================================================= */

/* ---- THE HERO IS ONE COLUMN AND ONE PICTURE ----------------------------- */

.tiles.live .tile { display: flex; flex-direction: column-reverse; align-items: start; gap: 0; }
.tiles.live dd { font-size: var(--step-1); color: var(--c-gold-soft); }

/* ---- 3. THE TABLES BECOME A LIST OF CARDS -------------------------------
   THE CHOICE, AND WHY IT IS NOT THE SCROLLING ONE. Both were allowed. A
   scroller with a fade at its edge keeps the page short, and it still asks a
   person to discover that a table they can read is only three fifths of a
   table. The ranking's last two columns are the guild and the score -- the
   score is what the ranking is SORTED BY, so the column being silently absent
   means the page never shows the reason the rows are in the order they are in.
   A card cannot hide a column: every field is written, with its own heading
   beside it, and nothing depends on the reader trying a gesture.

   THE COST IS HEIGHT and it was measured: /ranking at 390 goes from 1393px to
   about 1900px for eight rows -- a row costs 77px as a card against 44px as a
   table row. That is the price of the two columns being there at all.

   43.75rem, measured rather than borrowed from the breakpoints above:
   table.rank declares a 40rem minimum and the gutter at that width is 27px a
   side, so the table stops fitting -- and starts hiding columns -- at about
   700px. Above it the table is a table, which is the better shape when it
   fits. A tablet at 768 therefore keeps the real table; a phone never sees it.

   The heading row is not deleted, it is moved out of sight: the cells still
   need something to be the header OF, and the roles in the markup (role=table,
   rowgroup, row, cell, columnheader) are there because changing an element's
   display is what makes a browser stop treating a table as one. */
@media (max-width: 43.75rem) {

	/* .orders carries its own min-width further up the file, and a class more
	   than this rule has -- so it has to be named, or the order table keeps a
	   448px floor, breaks out of the account column and scrolls the whole page
	   sideways. Measured before this line: the document was 485px wide on a
	   390px screen. */
	table.rank, table.rank.orders { display: block; min-width: 0; }
	table.rank thead {
		position: absolute; width: 1px; height: 1px;
		padding: 0; margin: -1px; overflow: hidden;
		clip-path: inset(50%); white-space: nowrap;
	}
	/* The row and its cells collapse too. A table-row inside a 1px box still
	   lays itself out at its natural width -- invisible, but it measures as a
	   box hanging 8px past the right edge of a 390px screen, which is exactly
	   the kind of thing an overflow check is supposed to catch. */
	table.rank thead tr, table.rank thead th { display: block; }
	table.rank tbody { display: grid; gap: var(--s-3); }
	table.rank tbody tr {
		display: grid;
		gap: var(--s-1) var(--s-3);
		padding: var(--s-3) var(--s-4);
		background: var(--c-well);
		border: var(--bw) solid var(--c-hair);
		border-radius: var(--r);
		/* A row is a target now: it is the height of a card, which is well past
		   the 44px a finger needs. */
		align-items: baseline;
	}
	table.rank td { display: block; border: 0; padding: 0; }
	/* THE HEADING TRAVELS WITH THE VALUE. data-label carries the same phrase
	   the column heading does -- the template writes both from one dictionary
	   key -- so the two cannot say different things. Dimmed and small: it is a
	   label, and a card whose labels are as loud as its values is a form. */
	table.rank td[data-label]::before {
		content: attr(data-label) " ";
		color: var(--c-ink-faint);
		font-family: var(--f-display);
		font-weight: var(--w-medium);
		font-size: var(--step--2);
		text-transform: uppercase;
		letter-spacing: var(--ls-wide);
	}

	/* FIVE COLUMNS -- both ranking tables have the same shape: a place, a
	   name, a level, a guild (or a leader) and a score. Two lines: who, then
	   the three facts about them, with the place down the left of both. */
	table.rank:not(.orders) tbody tr {
		grid-template-columns: 2.25rem minmax(0, 1fr) auto;
	}
	table.rank:not(.orders) td:nth-child(1) {
		grid-area: 1 / 1 / 3 / 2;
		font-family: var(--f-mono);
		font-size: var(--step-2);
		line-height: var(--lh-tight);
		font-variant-numeric: tabular-nums;
	}
	table.rank:not(.orders) td:nth-child(2) {
		grid-area: 1 / 2 / 2 / 3;
		font-weight: var(--w-semibold);
		overflow-wrap: anywhere;
	}
	table.rank:not(.orders) td:nth-child(3) { grid-area: 1 / 3 / 2 / 4; text-align: end; white-space: nowrap; }
	table.rank:not(.orders) td:nth-child(4) { grid-area: 2 / 2 / 3 / 3; font-size: var(--step--1); overflow-wrap: anywhere; }
	table.rank:not(.orders) td:nth-child(5) { grid-area: 2 / 3 / 3 / 4; font-size: var(--step--1); text-align: end; white-space: nowrap; }

	/* FOUR COLUMNS -- a purchase: what was bought, then when, for how much and
	   where it got to. The product leads because it is the one field a person
	   is scanning for. */
	table.rank.orders tbody tr { grid-template-columns: minmax(0, 1fr) auto; }
	table.rank.orders td:nth-child(2) {
		grid-area: 1 / 1 / 2 / 3;
		font-weight: var(--w-semibold);
		overflow-wrap: anywhere;
	}
	table.rank.orders td:nth-child(1) { grid-area: 2 / 1 / 3 / 2; font-size: var(--step--1); }
	table.rank.orders td:nth-child(3) { grid-area: 2 / 2 / 3 / 3; font-size: var(--step--1); text-align: end; white-space: nowrap; }
	table.rank.orders td:nth-child(4) { grid-area: 3 / 1 / 4 / 3; font-size: var(--step--1); }

	/* The mark on the visitor's own row moves from the first CELL to the card,
	   because there are no cells here any more -- td has given up its border
	   along with its padding. The wash carries over untouched. */
	table.rank tbody tr.rank-mine { border-inline-start: var(--bw-mark) solid var(--c-gold); }

	/* The two-column specification table on /download fits as a table at every
	   width (18rem minimum), so it is left alone -- but its scroller no longer
	   needs to be one either. */
	table.spec { min-width: 0; }
}

/* ---- 4. THINGS A FINGER HAS TO HIT --------------------------------------
   44px in both directions, from --tap. Split in two: what is only on the page
   below the menu breakpoint goes in the width query, because the burger is
   display:none above it and a rule keyed on the pointer alone would bring it
   back on a touchscreen laptop. Everything that is a small link at any width
   goes in the pointer query. */
@media (max-width: 51.25rem) {
	.menu > summary {
		display: grid;
		place-items: center;
		min-inline-size: var(--tap);
		min-block-size: var(--tap);
		padding: 0;
		line-height: 0;
	}
	/* The wordmark is the way home from every page. */
	.brand { display: inline-flex; align-items: center; min-block-size: var(--tap); }
	/* The strip's link: it stretches to the strip's full height, which is what
	   makes the taller --h-ann on a phone worth having. */
}

/* WIDTH OR POINTER, and the width is not a convenience. A real phone reports a
   coarse pointer and would be covered by the second half alone -- but a desktop
   window dragged down to 390px reports a fine one, and that is the window this
   work is checked in. A rule that only exists on hardware nobody is holding is
   a rule nobody can measure. */
@media (max-width: 51.25rem), (pointer: coarse) {
	.field-note a,
.linky {
		display: inline-block;
		min-block-size: var(--tap);
		min-inline-size: var(--tap);
		padding-block: var(--s-2);
		/* A one-word link ("Sıfırla", "Tümü") is 29px wide, so the box has to be
		   wider than the word; centring is what stops the word sitting against
		   the left edge of its own target. */
		text-align: center;
	}
	.tab { min-block-size: var(--tap); display: grid; place-items: center; }

	

	/* THE STRIP'S LINK STRETCHES TO THE STRIP'S FULL HEIGHT, and BOTH boxes
	   have to be told: the strip centres its .wrap, so stretching only inside
	   the wrap stretches to the wrap's own 23px and stops there. The strip
	   itself is taller here -- see --h-ann in tokens.css. */
	.ann { align-items: stretch; }
	.ann > .wrap { align-items: stretch; }
	.ann .tag, .ann-text { align-self: center; }
	.ann-more {
		display: flex;
		align-items: center;
		justify-content: center;
		min-inline-size: var(--tap);
	}
}

/* THE SLOT. Recessed rather than raised -- an inset well with a hairline -- so
   it reads as a socket the icon is sitting in. The icon is centred and NEVER
   scaled up past its own pixels: max-width/height only. A 32x32 sprite blown up
   to fill 4.5rem is a blurred smear, and image-rendering: pixelated is the
   answer only when the scale is a whole multiple, which it is not for every
   icon in the game. */
.slot {
	position: relative;
	overflow: hidden;
	display: grid;
	place-items: center;
	inline-size: var(--sz-slot);
	block-size: var(--sz-slot);
	background: var(--c-well);
	border: var(--bw) solid var(--c-line);
	border-radius: var(--r-sm);
	box-shadow: inset 0 1px 0 rgb(0 0 0 / .35);
}
/* ABSOLUTE, NOT PERCENTAGE SIZED -- measured, not assumed. With
   `max-block-size: 100%` the browser resolved the height as auto and a 32x64
   costume icon came out at twice the slot's height, hanging over the name and
   the row below it. Anchoring to the slot's own box with inset:0 makes the
   height definite; object-fit keeps the sprite's proportions inside it. */
.slot img {
	position: absolute;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
	image-rendering: pixelated;
}
/* The same chip is a <button> on the site and an <a> on the market pages. The
   rule above already sets every box property, so the link needs only the two
   things a link brings with it and a button does not. */
a.ep-chip { text-decoration: none; }
.box {
	position: relative;
	display: grid;
	justify-items: center;
	gap: var(--s-2);
	height: 100%;
	padding: var(--s-5) var(--s-4) var(--s-4);
	text-align: center;
	color: inherit;
	background: linear-gradient(180deg, var(--c-panel), var(--c-ground-2));
	border: var(--bw) solid var(--c-line);
	border-radius: var(--r);
	overflow: hidden;
	transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.box:hover { border-color: var(--c-gold-edge); }
.box:focus-visible { outline: 2px solid var(--c-gold); outline-offset: 2px; }

/* THE FRAME IS THE SIGNATURE: an inventory square. A recessed well, a hairline,
   a black line inset a pixel inside it -- which is what makes a box read as
   forged rather than as a div -- and four corner ticks, drawn with borders
   rather than an image. */
.frame {
	position: relative;
	display: block;
	padding: var(--s-2);
	background: linear-gradient(180deg, var(--c-raise), var(--c-well));
	border: var(--bw) solid var(--c-line-hi);
	border-radius: var(--r-sm);
	box-shadow: inset 0 0 0 1px rgb(0 0 0 / .45), inset 0 2px 6px rgb(0 0 0 / .35);
}
.box:hover .frame { border-color: var(--c-gold-edge); }
.frame::before, .frame::after {
	content: "";
	position: absolute;
	inline-size: 11px;
	block-size: 11px;
	border-color: var(--c-gold-dim);
	opacity: .5;
	transition: opacity var(--t-fast) var(--ease);
}
.frame::before { inset-block-start: 4px; inset-inline-start: 4px; border-block-start: 1px solid; border-inline-start: 1px solid; }
.frame::after  { inset-block-end: 4px;  inset-inline-end: 4px;  border-block-end: 1px solid;  border-inline-end: 1px solid; }
.box:hover .frame::before, .box:hover .frame::after { opacity: 1; }
/* Inside a frame the slot is only a box of the right size: the well, the
   hairline and the shadow belong to the frame. */
.frame .slot { background: none; border: 0; box-shadow: none; border-radius: 0; }

/* How many the pack holds, in the corner of the square -- where the game puts a
   stack count and where a player already looks for it. */
.qty {
	position: absolute;
	inset-block-end: 4px;
	inset-inline-end: 6px;
	font-style: normal;
	font-family: var(--f-mono);
	font-size: var(--step--1);
	color: var(--c-ink);
	text-shadow: 0 1px 2px #000, 0 0 3px #000;
}

/* ---- EP yükle ------------------------------------------------------------ */

/* A split, not a centred card: the figure that is about to change on the left,
   the one field that changes it beside it. */
/* ONE COLUMN. This was a two-column grid and the children fell into it in
   DOM order -- label left, balance in the RIGHT column, form back on the left
   one row down -- so the figure floated away from its own label and the whole
   right side stayed empty. Three things that belong together, in three places.
   Stacked, they read as one sentence: this is what you have, this is how it
   grows, this is where you go next. */
.topup {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s-4);
	padding-block-start: var(--s-3);
	border-block-start: var(--bw) solid var(--c-hair);
}

@media (max-width: 40rem) {
	.topup { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
}
a.pgbtn:hover { border-color: var(--c-gold-dim); color: var(--c-gold); }

/* ============================================================================
   THE PORTAL FRAME (2026-10-06)

   Every page sits in a three-column portal over a full-page painting: the
   side menu and the download on the left, the page in the middle, the account
   box and the ladder on the right. The painting and the column count are
   render.portalScenes' decision, keyed by template; nothing here knows which
   page it is on except through the two class hooks that table produces
   (.s-<art> on the painting, .pt-wide / .pt-solo on the portal).

   EVERY CLASS HERE IS pt-*. The page bodies still carry the previous design's
   class names (.bar, .menu, .tabs, .rank ...) and keep their rules until they
   move onto the parchment; a frame that reused those names would restyle the
   bodies by accident, and a body that reused the frame's would do the same in
   the other direction.
   ========================================================================= */

html.ann-on body { padding-block-start: var(--h-ann); }

/* ---- the painting and the embers ---------------------------------------- */
.pt-world {
	position: fixed; inset: 0; z-index: -2;
	background: var(--c-ground) no-repeat 50% 0 / cover;
}
.pt-world::after {
	content: ""; position: absolute; inset: 0;
	background:
		radial-gradient(ellipse 70% 55% at 50% 6%, var(--pt-glow), transparent 70%),
		linear-gradient(var(--pt-veil-top), transparent 16%, var(--pt-veil-mid) 40%, var(--pt-veil-low) 80%);
}
/* WebP at 1920 wide for anything landscape-ish, and a 640-wide portrait cut
   of the same painting for phones held upright: a phone shows only the
   middle quarter of a 16:9 picture under cover, so it is sent only that.
   Only the rule that matches downloads its picture. */
.s-duo     { background-image: url("/assets/img/bg-duo.8759dc7e.webp"); }
.s-four    { background-image: url("/assets/img/bg-four.32cb6296.webp"); }
.s-sultan  { background-image: url("/assets/img/bg-sultan.db854b8c.webp"); }
.s-magi    { background-image: url("/assets/img/bg-magi.361fb368.webp"); }
.s-heroine { background-image: url("/assets/img/bg-heroine.0f1a558d.webp"); }
.s-demon   { background-image: url("/assets/img/bg-demon.075ce2cc.webp"); }
.s-war     { background-image: url("/assets/img/bg-war.d2fc4f88.webp"); }
.s-capital { background-image: url("/assets/img/bg-capital.f29b6879.webp"); }
@media (max-aspect-ratio: 3/5) {
	.s-duo     { background-image: url("/assets/img/bg-duo-p.d020cae9.webp"); }
	.s-four    { background-image: url("/assets/img/bg-four-p.e5e38b75.webp"); }
	.s-sultan  { background-image: url("/assets/img/bg-sultan-p.7319de91.webp"); }
	.s-magi    { background-image: url("/assets/img/bg-magi-p.b6a58ec1.webp"); }
	.s-heroine { background-image: url("/assets/img/bg-heroine-p.2499c550.webp"); }
	.s-demon   { background-image: url("/assets/img/bg-demon-p.89c094eb.webp"); }
	.s-war     { background-image: url("/assets/img/bg-war-p.9c27e25a.webp"); }
	.s-capital { background-image: url("/assets/img/bg-capital-p.9687f933.webp"); }
}
/* A phone gets the painting still: a full-screen layer kept scaling on the GPU
   costs battery for a movement nobody sees under the panels. */
.pt-embers { position: fixed; inset: 0; z-index: -1; inline-size: 100%; block-size: 100%; pointer-events: none; }

/* ---- the bar ------------------------------------------------------------- */
.pt-bar {
	position: sticky; inset-block-start: var(--ann-top); z-index: 50;
	block-size: 62px;
	transition: background 900ms var(--pt-ease), box-shadow 900ms var(--pt-ease); /* slow on purpose: the bar darkens as the art slides under it */
}
.pt-bar.pt-solid, html:not(.js) .pt-bar {
	background: linear-gradient(var(--pt-bar), var(--pt-bar-2));
	box-shadow: 0 1px 0 var(--pt-rail-glow), 0 10px 30px var(--pt-shadow);
}
.pt-bar-in {
	block-size: 100%; inline-size: min(1200px, 100% - 32px); margin-inline: auto;
	display: flex; align-items: center; gap: var(--s-4);
}
.pt-menu { margin-inline-end: auto; }
.pt-menu::details-content { content-visibility: visible; }
.pt-menu > summary { display: none; }
.pt-nav { display: flex; gap: 2px; }
.pt-nav a {
	position: relative; padding: 8px 11px;
	font: 16px var(--f-portal);
	color: var(--c-ink); text-decoration: none; text-shadow: 0 1px 3px var(--pt-black); white-space: nowrap;
	transition: color var(--t) var(--pt-ease), text-shadow var(--t) var(--pt-ease);
}
/* HOVER: a gold brush stroke is drawn under the word and a small ruby appears
   above it. Both are revealed by clip-path / transform, never by layout. */
.pt-nav a::after {
	content: ""; position: absolute; inset-inline: 8px; inset-block-end: 0; block-size: 8px;
	background: var(--pt-brush-solid) center / 100% 100% no-repeat;
	clip-path: inset(0 100% 0 0); transition: clip-path .5s var(--pt-ease);
}
.pt-nav a::before {
	content: ""; position: absolute; inset-inline-start: 50%; inset-block-start: 0;
	inline-size: 7px; block-size: 7px; margin-inline-start: -3.5px;
	transform: rotate(45deg) scale(0);
	background: radial-gradient(circle at 35% 30%, var(--pt-ruby-hi), var(--pt-ruby-mid) 50%, var(--pt-ruby-lo));
	box-shadow: 0 0 8px var(--pt-ruby); transition: transform .4s var(--pt-ease);
}
.pt-nav a:hover, .pt-nav a.on { color: var(--c-gold-hi); }
.pt-nav a:hover { text-shadow: 0 0 10px var(--pt-ember), 0 1px 3px var(--pt-black); }
.pt-nav a:hover::after, .pt-nav a.on::after { clip-path: inset(0 0 0 0); }
.pt-nav a:hover::before, .pt-nav a.on::before { transform: rotate(45deg) scale(1); }
.pt-rank-head { display: flex; align-items: center; gap: 10px; margin: 0 0 16px; }
.pt-rank-head .pt-title { flex: 1; margin: 0; min-inline-size: 0; }
.pt-rank .live-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--c-ink-dim); white-space: nowrap; }
.pt-rank .live-chip b { color: var(--c-ink); }
.pt-rank .live-dot { position: relative; }
.pt-rank .live-dot::after {
	content: ""; position: absolute; inset: 0; border-radius: 50%;
	box-shadow: 0 0 0 4px var(--pt-live-ring);
	animation: pt-ping 2.4s infinite;
}
@keyframes pt-ping { 0% { transform: scale(.6); opacity: 1; } 80%, 100% { transform: scale(2); opacity: 0; } }
.pt-doors { display: inline-flex; align-items: center; gap: var(--s-2); }
.pt-bar .who-link { padding: 0; gap: 9px; text-shadow: 0 1px 3px var(--pt-black); }
.pt-bar .who-link:hover { background: none; }
.pt-bar .who, .pt-acct .who { font-size: 16px; color: var(--c-ink); white-space: nowrap; }
.pt-bar .who-link:hover .who, .pt-me:hover .who { color: var(--c-gold-hi); }
.pt-bar .who-badge, .pt-acct .who-badge {
	inline-size: 30px; block-size: 30px; border: 0;
	font: 13px var(--f-portal); color: var(--pt-gold-ink);
	background: linear-gradient(var(--pt-gold-a), var(--pt-gold-c));
	box-shadow: 0 0 0 1px var(--pt-gold-edge), 0 0 0 2px var(--pt-gold-ring);
}

/* ---- the portal ---------------------------------------------------------- */
.pt-portal {
	flex: 1 0 auto;
	inline-size: min(1200px, 100% - 32px); margin: var(--s-4) auto 0;
	display: grid; grid-template-columns: 240px minmax(0, 1fr) 270px; gap: 26px; align-items: start;
}
.pt-portal.pt-wide { grid-template-columns: 240px minmax(0, 1fr); }
.pt-portal.pt-solo { grid-template-columns: minmax(0, 760px); justify-content: center; }
.pt-col { display: grid; gap: 28px; min-inline-size: 0; grid-template-columns: minmax(0, 1fr); }
.pt-mid { min-inline-size: 0; padding-block-end: 70px; }

/* ---- the gilded panel ---------------------------------------------------- */
.pt-frame {
	position: relative; padding: 30px 24px 30px;
	background:
		radial-gradient(ellipse at 50% 0%, var(--pt-wood-hi), transparent 60%),
		linear-gradient(var(--pt-wood), var(--pt-wood-2));
	border: 1px solid var(--pt-black);
	box-shadow:
		inset 0 0 0 2px var(--pt-rail), inset 0 0 0 3px var(--pt-black),
		inset 0 0 0 4px var(--pt-rail-gold), inset 0 0 0 5px var(--pt-black),
		inset 0 0 40px var(--pt-inset),
		0 0 0 1px var(--pt-rail-glow), 0 18px 40px var(--pt-shadow);
}
.pt-c {
	position: absolute; inline-size: 66px; block-size: 66px; pointer-events: none;
	background: url("/assets/img/corner.5b6cc869.webp") center / contain no-repeat;
	filter: drop-shadow(0 3px 4px var(--pt-shadow));
}
.pt-tl { inset-block-start: -12px; inset-inline-start: -12px; }
.pt-tr { inset-block-start: -12px; inset-inline-end: -12px; transform: scaleX(-1); }
.pt-bl { inset-block-end: -12px; inset-inline-start: -12px; transform: scaleY(-1); }
.pt-br { inset-block-end: -12px; inset-inline-end: -12px; transform: scale(-1); }
/* A frame that holds a parchment sheet: the sheet is the content, the wood is
   only its border. */
.pt-tight { padding: 10px; }

.pt-title {
	display: flex; align-items: center; gap: 10px; margin: 0 0 16px;
	font: 20px var(--f-portal);
	color: var(--c-gold-hi); text-shadow: 0 1px 0 var(--pt-black);
}
.pt-title::after { content: ""; flex: 1; block-size: 1px; background: linear-gradient(90deg, var(--pt-rail-gold), transparent); }

/* ---- the side menu ------------------------------------------------------- */
.pt-side h2 { margin: 16px 0 6px; font: 17px var(--f-portal); color: var(--c-gold); }
.pt-grp:first-child h2 { margin-block-start: 0; }
.pt-side ul, .pt-acct ul { list-style: none; margin: 0; padding: 0; }
.pt-side li { position: relative; }
.pt-side a {
	position: relative; display: flex; align-items: center; gap: 10px; padding: 6px 10px 6px 12px;
	font-size: 16px; color: var(--c-ink); text-decoration: none;
	transition: color .35s var(--pt-ease), text-shadow .35s var(--pt-ease), padding .35s var(--pt-ease);
}
.pt-side a::before {
	content: ""; inline-size: 6px; block-size: 6px; flex: none; transform: rotate(45deg);
	background: var(--c-gold-dim); box-shadow: 0 0 0 1px var(--pt-black);
	transition: transform .5s var(--pt-ease), background .4s, box-shadow .4s;
}
/* HOVER: the bullet catches fire and turns into a ruby, a gold brush stroke
   is drawn under the word, and a few sparks rise from the bullet. */
.pt-side a::after {
	content: ""; position: absolute; inset-inline: 26px 6px; inset-block-end: 1px; block-size: 9px; pointer-events: none;
	background: var(--pt-brush) left center / 100% 100% no-repeat;
	clip-path: inset(0 100% 0 0); transition: clip-path .55s var(--pt-ease);
}
.pt-side a:hover {
	padding-inline-start: 16px; color: var(--pt-ember-ink);
	text-shadow: 0 0 10px var(--pt-ember), 0 0 2px var(--pt-ember-2);
}
.pt-side a:hover::before {
	transform: rotate(225deg) scale(1.45);
	background: radial-gradient(circle at 35% 30%, var(--pt-ruby-hi), var(--pt-ruby-mid) 45%, var(--pt-ruby-lo));
	box-shadow: 0 0 0 1px var(--pt-ruby-edge), 0 0 8px var(--pt-ruby), 0 0 16px var(--pt-ruby-glow);
}
.pt-side a:hover::after, .pt-side a[aria-current]::after { clip-path: inset(0 0 0 0); }
.pt-side a[aria-current]::after { opacity: .55; }
.pt-side a[aria-current] { color: var(--c-gold-hi); }
.pt-side a[aria-current]::before { background: var(--pt-ruby); box-shadow: 0 0 8px var(--pt-ruby); }
.pt-side li::after {
	content: ""; position: absolute; inset-inline-start: 14px; inset-block-start: 50%;
	inline-size: 2px; block-size: 2px; border-radius: 50%; opacity: 0; pointer-events: none;
	background: var(--pt-spark-a);
	box-shadow: 3px -4px 0 0 var(--pt-spark-b), -3px -7px 0 0 var(--pt-spark-c), 1px -11px 0 0 var(--pt-spark-a);
}
.pt-side li:hover::after { animation: pt-sparks 1s ease-out infinite; }
@keyframes pt-sparks {
	0% { opacity: 0; transform: translateY(2px) scale(.6); }
	25% { opacity: 1; }
	100% { opacity: 0; transform: translateY(-14px) scale(1); }
}

/* ---- metal buttons ------------------------------------------------------- */
.pt-btn {
	position: relative; isolation: isolate; overflow: hidden;
	display: inline-flex; align-items: center; justify-content: center; gap: 10px;
	block-size: 44px; padding: 0 22px; border: 0; border-radius: 3px; cursor: pointer;
	font: 15px/1 var(--f-portal); white-space: nowrap;
	color: var(--pt-gold-ink); text-decoration: none;
	background: linear-gradient(var(--pt-gold-a), var(--pt-gold-b) 38%, var(--pt-gold-c) 62%, var(--pt-gold-d));
	box-shadow: 0 0 0 1px var(--pt-gold-edge), 0 0 0 2px var(--pt-gold-ring), 0 8px 18px var(--pt-shadow);
	transition: transform var(--t) var(--pt-ease), filter var(--t) var(--pt-ease);
}
.pt-btn::after {
	content: ""; position: absolute; inset-block: -2px; inset-inline-start: -40%; inline-size: 30%; z-index: -1;
	transform: skewX(-20deg); background: linear-gradient(90deg, transparent, var(--pt-sheen), transparent);
	animation: pt-sheen 5s var(--pt-ease) infinite;
}
/* Moved by transform, not by its inset: an inset animation re-laid-out the
   button every frame; a transform does not touch layout at all. */
@keyframes pt-sheen {
	0%, 62% { transform: translateX(0) skewX(-20deg); }
	88%, 100% { transform: translateX(570%) skewX(-20deg); }
}
.pt-btn:hover { filter: brightness(1.08) saturate(1.1); transform: translateY(-2px); }
.pt-btn:active { transform: translateY(0) scale(.985); }
.pt-btn svg { inline-size: 20px; block-size: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: square; }
.pt-stone {
	color: var(--c-ink);
	background: linear-gradient(var(--pt-stone-a), var(--pt-stone-b) 55%, var(--pt-stone-c));
	box-shadow: 0 0 0 1px var(--pt-black), 0 6px 14px var(--pt-shadow);
}
.pt-stone::after { display: none; }
.pt-stone:hover { color: var(--c-gold-hi); }
.pt-full { inline-size: 100%; }
.pt-sm { block-size: 34px; padding: 0 16px; font-size: 13px; }
.pt-ghost {
	color: var(--c-gold-hi); text-shadow: 0 1px 2px var(--pt-black);
	background: var(--pt-ghost); box-shadow: inset 0 0 0 1px var(--pt-ghost-line);
}
.pt-ghost::after { display: none; }
.pt-ghost:hover { color: var(--c-ink); }

.pt-dl { text-align: center; }
.pt-dl .pt-btn { block-size: 58px; padding: 0 12px; font-size: 15.5px; }
.pt-dl p { margin: 10px 0 0; font-size: var(--step--1); color: var(--c-ink-faint); }

/* ---- the account box ----------------------------------------------------- */
.pt-acct { display: grid; gap: 12px; }
.pt-acct .pt-title { margin: 0 0 4px; }
.pt-me { display: inline-flex; align-items: center; gap: 9px; margin: 0; text-decoration: none; }
.pt-acct .who-badge { inline-size: 40px; block-size: 40px; font-size: 16px; }
.pt-bal {
	display: flex; justify-content: space-between; align-items: baseline; margin: 0; padding: 10px 12px;
	background: var(--pt-shadow); border: 1px solid var(--pt-rail-glow); border-radius: 2px;
	font-size: 12px; color: var(--c-ink-dim);
}
.pt-bal b { font: 20px var(--f-portal); color: var(--c-gold-hi); font-variant-numeric: tabular-nums; }
.pt-bal b::after { content: " EP"; font-size: 13px; }
.pt-links { display: grid; gap: 2px; }
.pt-links a, .pt-out {
	display: flex; justify-content: space-between; inline-size: 100%; padding: 7px 4px;
	font: 16px var(--f-text); color: var(--c-ink); text-decoration: none; text-align: start;
	background: none; border: 0; border-block-end: 1px solid var(--pt-row); cursor: pointer;
}
.pt-links a:hover, .pt-out:hover { color: var(--c-gold-hi); }

/* ---- the ladder ---------------------------------------------------------- */
.pt-tabh {
	margin: 12px 0 6px;
	font: 14px var(--f-portal); color: var(--c-gold);
}
.pt-rank .pt-tabs {
	position: relative; display: grid; grid-template-columns: 1fr 1fr; margin: 0 0 10px;
	border: 1px solid var(--pt-tab-line); border-radius: var(--r-sm); overflow: hidden;
}
.pt-tabs::before {
	content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; inline-size: 50%;
	background: linear-gradient(var(--pt-tab-a), var(--pt-tab-b)); transition: transform var(--t-slow) var(--pt-ease);
}
.pt-tabs[data-on="1"]::before { transform: translateX(100%); }
.pt-tab {
	position: relative; z-index: 1; block-size: 32px; border: 0; background: none; cursor: pointer;
	font: 14px var(--f-portal); color: var(--c-ink-dim);
}
.pt-tab[aria-selected="true"] { color: var(--pt-gold-ink); }
.pt-list { list-style: none; margin: 0; padding: 0; counter-reset: pt-r; }
.pt-list[hidden] { display: none; }
.pt-list li {
	display: grid; grid-template-columns: 24px 1fr auto; align-items: center; gap: 8px;
	block-size: 31px; padding: 0 8px; font-size: 15px; border-block-end: 1px solid var(--pt-row);
	transition: background var(--t) ease, transform var(--t) var(--pt-ease);
}
.pt-list li:hover { background: var(--pt-row-hi); transform: translateX(3px); }
.pt-list li::before {
	counter-increment: pt-r; content: counter(pt-r);
	font: 14px var(--f-portal); color: var(--c-ink-faint); text-align: center;
}
.pt-list li:nth-child(1)::before { color: var(--pt-rank-1); }
.pt-list li:nth-child(2)::before { color: var(--pt-rank-2); }
.pt-list li:nth-child(3)::before { color: var(--pt-rank-3); }
.pt-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.pt-dia {
	display: inline-block; inline-size: 7px; block-size: 7px; margin-inline-end: 8px; vertical-align: 1px;
	transform: rotate(45deg); background: var(--c-class, var(--c-gold)); box-shadow: 0 0 6px var(--c-class, var(--c-gold));
}
.pt-lv { font-size: 13px; color: var(--c-ink-dim); font-variant-numeric: tabular-nums; }
.pt-more { display: block; margin: 12px 0 0; text-align: center; font-size: 14px; color: var(--c-gold-hi); }

/* ---- the footer ---------------------------------------------------------- */
.pt-foot {
	position: relative; margin-block-start: 40px; padding: 70px 16px 34px; text-align: center;
	font-size: var(--step--1); color: var(--c-ink-faint);
	background: linear-gradient(transparent, var(--pt-foot) 40%);
}

.pt-foot nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 22px; margin: 12px 0 8px; }
.pt-foot a { color: var(--c-ink-dim); text-decoration: none; transition: color var(--t) ease; }
.pt-foot a:hover { color: var(--c-gold-hi); }
.pt-foot p { margin: 0; text-align: center; }

/* ---- narrower screens ---------------------------------------------------- */
@media (max-width: 1100px) {
	.pt-portal, .pt-portal.pt-wide { grid-template-columns: minmax(0, 1fr) 270px; }
	.pt-left { grid-column: 1 / -1; order: 3; }
	.pt-groups { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 24px; }
	.pt-grp:nth-child(-n+3) h2 { margin-block-start: 0; }
	.pt-nav a { padding: 8px 7px; }
}
@media (max-width: 900px) {
	.pt-menu { order: 3; margin-inline-start: auto; margin-inline-end: 0; }
	.pt-doors { margin-inline-start: auto; }
	.pt-menu > summary {
		display: grid; place-items: center; inline-size: 42px; block-size: 42px; cursor: pointer; list-style: none;
		border: 1px solid var(--pt-rail-gold); border-radius: 3px; background: var(--pt-shadow);
	}
	.pt-menu > summary::-webkit-details-marker { display: none; }
	.pt-menu > summary span, .pt-menu > summary span::before, .pt-menu > summary span::after {
		display: block; inline-size: 18px; block-size: 2px; background: var(--c-gold-hi); position: relative;
	}
	.pt-menu > summary span::before, .pt-menu > summary span::after { content: ""; position: absolute; inset-inline-start: 0; }
	.pt-menu > summary span::before { inset-block-start: -6px; }
	.pt-menu > summary span::after { inset-block-start: 6px; }
	/* NOT content-visibility:auto -- that implies layout+paint containment, which made the
	   45px summary box the containing block of the absolutely positioned link list and
	   clipped it: on phones the menu "opened" into a 42px-wide invisible column (v0.67.2). */
	.pt-menu:not([open]) > .pt-nav { display: none; }
	.pt-menu[open] > .pt-nav {
		position: absolute; inset-inline: 0; inset-block-start: 62px; display: grid; padding: 8px 16px 16px;
		background: linear-gradient(var(--pt-bar), var(--pt-bar-2)), var(--c-ground); box-shadow: 0 1px 0 var(--pt-rail-glow), 0 14px 30px var(--pt-shadow);
	}
	.pt-menu[open] > .pt-nav a { padding: 12px 4px; font-size: 14px; border-block-end: 1px solid var(--pt-row); }
	.pt-bar { background: linear-gradient(var(--pt-bar), var(--pt-bar-2)); }
}
@media (max-width: 760px) {
	.pt-portal, .pt-portal.pt-wide { grid-template-columns: minmax(0, 1fr); inline-size: calc(100% - 24px); }
	.pt-right { order: 2; }
	.pt-groups { grid-template-columns: 1fr 1fr; }
	.pt-grp:nth-child(3) h2 { margin-block-start: 16px; }
	.pt-col { gap: 46px; }
	.pt-frame { padding: 22px 16px 22px; }
	.pt-bar-in { inline-size: calc(100% - 24px); gap: var(--s-2); }
}
@media (prefers-reduced-motion: reduce) {
	.pt-btn::after, .pt-rank .live-dot::after, .pt-side li:hover::after { animation: none; }
	.pt-embers { display: none; }
}

/* ---- BOOK-HAND TYPE (Baran, 2026-10-06: option D, Grenze + EB
   Garamond). A blackletter reads badly in capitals and with wide tracking. Every rule above and in the page files
   that still asks for uppercase or letter-spacing was written for the
   previous faces; this undoes all of them at once rather than editing two
   hundred declarations, which is also what the approved design does. */
body, body * { text-transform: none !important; letter-spacing: .2px !important; }


/* ---- the frame's sign-in box (every signed-out page, 2026-10-06) --------- */
.pt-login .form { display: grid; gap: 11px; }
.pt-login .field > span { font-size: 13px; }
.pt-check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--c-ink-dim); cursor: pointer; }
.pt-check input { width: 16px; height: 16px; margin: 0; accent-color: var(--c-gold); }
/* Flexible widget scaled to the 220px fields: 300px * 0.7334 = 220px wide, 65px * 0.7334 = 48px
   high; the negative margins give back the layout space the unscaled box would take. */
.pt-login .cf-turnstile { inline-size: 300px; block-size: 65px; transform: scale(.7334); transform-origin: 0 0; margin: 0 -80px -17px 0; }
@media (max-width: 760px) { .pt-login .cf-turnstile { inline-size: auto; transform: none; margin: 0; } }
.pt-flinks { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 4px; font-size: 14px; color: var(--c-ink-dim); }
.pt-flinks a { color: var(--c-gold); }
.pt-flinks a:hover { color: var(--c-gold-hi); }

/* content.css */
/* Page bodies that the design preview did not draw. Everything else on the
   pages is in zd.css (the design, generated) and zz-port.css (the few
   adjustments the real markup needs). */

/* zd.css */
/* ============================================================================
   PAGE BODIES, AS THE APPROVED DESIGN DRAWS THEM (2026-10-06).

   GENERATED from the design preview's own stylesheet (kit.css parchment,
   forms, alerts, tables, cards, banner, plus the three page groups' extras)
   by renaming every class to d-<class> and every custom property to
   --d-<name>. The prefix is the point: the site's older rules used many of the
   same short names (.card, .kv, .chip, .frame ...), and a design rule that
   matched an older element -- or the reverse -- would restyle a page nobody
   was looking at. @container queries became @media queries with the same
   widths. Fonts are the site's (--f-portal, --f-text).
   ========================================================================= */
:root{
  --d-ground:#0C0A08; --d-well:#15100C; --d-panel:#1C1510; --d-raise:#241A13; --d-line:#3A2A1E;
  --d-ink:#EDE4D2; --d-ink-dim:#B6A891; --d-ink-faint:#7C7060;
  --d-gold:#C9A227; --d-gold-hi:#E3BE4A; --d-gold-lo:#8A701B; --d-gold-ink:#1B1305;
  --d-ember:#D8451F; --d-blood:#9E2414; --d-ok:#4E8C7A;
  --d-parch-ink:#3A2413; --d-parch-dim:#6E5236; --d-parch-red:#8A1C12; --d-parch-line:rgba(110,70,30,.35);
  --d-c-warrior:#E0552B; --d-c-assassin:#A4BC4C; --d-c-sura:#C78BE6; --d-c-shaman:#52BCD3;
  --d-display:var(--f-portal);
  --d-deco:var(--f-portal);
  --d-text:var(--f-text);
  --d-ease:cubic-bezier(.22,.8,.24,1);
}
.d-btn{--d-h:44px;position:relative;isolation:isolate;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;gap:10px;height:var(--d-h);padding:0 24px;
  font:700 13.5px/1 var(--d-display);letter-spacing:2px;color:#2a1a04;cursor:pointer;border:0;border-radius:3px;white-space:nowrap;text-transform:uppercase;
  background:linear-gradient(#fbe7a0,#e2bb4c 38%,#b38a22 62%,#e8c869);
  box-shadow:0 0 0 1px #3a2606,0 0 0 2px rgba(246,219,122,.35),inset 0 1px 0 rgba(255,255,255,.6),inset 0 -3px 6px rgba(80,50,0,.35),0 8px 18px rgba(0,0,0,.5);
  text-shadow:0 1px 0 rgba(255,240,190,.6);transition:transform .25s var(--d-ease),filter .25s var(--d-ease)}
.d-btn::after{content:"";position:absolute;inset:-2px auto -2px -40%;width:30%;z-index:-1;transform:skewX(-20deg);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.7),transparent);animation:d-sheen 5s var(--d-ease) infinite}
@keyframes d-sheen{0%,62%{left:-40%}88%,100%{left:130%}}
.d-btn:hover{filter:brightness(1.08) saturate(1.1);transform:translateY(-2px);color:#2a1a04}
.d-btn:active{transform:translateY(0) scale(.985)}
.d-btn.d-ruby{color:#ffe9c9;text-shadow:0 1px 2px #000;background:linear-gradient(#d13a2a,#9c1712 45%,#6c0c09 60%,#b52a1d);
  box-shadow:0 0 0 1px #2a0503,0 0 0 2px rgba(246,219,122,.55),inset 0 1px 0 rgba(255,190,160,.55),inset 0 -3px 8px rgba(0,0,0,.45),0 8px 22px rgba(0,0,0,.55)}
.d-btn.d-ruby:hover{color:#fff}
.d-btn.d-ghost{color:var(--d-gold-hi);text-shadow:0 1px 2px #000;background:rgba(14,9,6,.55);box-shadow:inset 0 0 0 1px rgba(246,219,122,.6)}
.d-btn.d-ghost::after{display:none}
.d-btn.d-ghost:hover{color:#fff}
.d-btn.d-stone{color:var(--d-ink);text-shadow:0 1px 1px #000;background:linear-gradient(#4a4038,#2c2520 55%,#3a322b);box-shadow:0 0 0 1px #000,inset 0 1px 0 rgba(255,255,255,.15),0 6px 14px rgba(0,0,0,.4)}
.d-btn.d-stone::after{display:none}
.d-btn.d-stone:hover{color:var(--d-gold-hi)}
.d-btn.d-big{--d-h:56px;padding:0 38px;font-size:16.5px;letter-spacing:3px}
.d-btn.d-sm{--d-h:34px;padding:0 16px;font-size:11.5px}
.d-btn.d-wide{width:100%}
.d-btn[disabled],.d-btn.d-off{filter:grayscale(.8) brightness(.7);cursor:not-allowed;transform:none}
.d-parch{position:relative;padding:30px 32px 40px;color:var(--d-parch-ink);
  background:
    radial-gradient(ellipse at 50% 40%,transparent 55%,rgba(110,70,30,.35)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.035' numOctaves='4' seed='9'/%3E%3CfeColorMatrix values='0 0 0 0 .45 0 0 0 0 .3 0 0 0 0 .12 0 0 0 .28 0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23p)'/%3E%3C/svg%3E"),
    linear-gradient(#efdfb6,#e2cb97);
  box-shadow:inset 0 0 0 1px rgba(90,55,20,.5),inset 0 0 60px rgba(120,75,30,.35)}
.d-parch a{color:var(--d-parch-red);font-weight:600}
.d-parch a:hover{text-decoration:underline}
.d-parch a.d-btn{color:#2a1a04;text-decoration:none}
.d-parch a.d-btn.d-ruby{color:#ffe9c9}
.d-parch a.d-btn.d-stone{color:var(--d-ink)}
.d-parch h1{margin:0 0 6px;font:900 28px/1.15 var(--d-deco);color:var(--d-parch-red);letter-spacing:.5px;text-wrap:balance}
.d-parch .d-lead{margin:0 0 22px;color:var(--d-parch-dim);font-size:15px;max-width:60ch}
.d-parch h2{display:flex;align-items:center;gap:12px;margin:26px 0 12px;font:900 18px var(--d-display);letter-spacing:1.5px;color:var(--d-parch-red)}
.d-parch h2:first-child{margin-top:0}
.d-parch h2::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,rgba(138,28,18,.5),transparent)}
.d-parch h2 a{order:2;font:600 12px var(--d-text);letter-spacing:.3px;color:var(--d-parch-dim)}
.d-parch h3{margin:18px 0 6px;font:700 15px var(--d-display);letter-spacing:.8px;color:var(--d-parch-ink)}
.d-parch p{margin:0 0 12px;max-width:68ch}
.d-parch ul.d-plain,.d-parch ol.d-plain{margin:0 0 14px;padding-left:20px}
.d-parch ul.d-plain li,.d-parch ol.d-plain li{margin:0 0 6px}
.d-parch hr{border:0;height:40px;margin:22px 0;background:url("/assets/img/crest.e19d99c8.webp") center/auto 40px no-repeat;opacity:.85}
.d-parch .d-small{font-size:12.5px;color:var(--d-parch-dim)}
.d-pform{display:grid;gap:14px;max-width:440px}
.d-pform.d-wide{max-width:none}
.d-pfield{display:grid;gap:5px}
.d-pfield>span{font:700 12.5px var(--d-text);letter-spacing:.3px;color:var(--d-parch-ink)}
.d-pfield input,.d-pfield select,.d-pfield textarea{width:100%;min-height:42px;padding:9px 12px;font:500 15px var(--d-text);color:var(--d-ink);background:#1a110b;
  border:1px solid #5a3d1c;border-radius:2px;box-shadow:inset 0 2px 6px rgba(0,0,0,.8),0 1px 0 rgba(255,255,255,.4);transition:border-color .3s,box-shadow .3s}
.d-pfield input:focus,.d-pfield select:focus,.d-pfield textarea:focus{outline:none;border-color:var(--d-gold);box-shadow:inset 0 2px 6px rgba(0,0,0,.8),0 0 0 3px rgba(201,162,39,.3)}
.d-pfield .d-hint{font-size:12.5px;color:var(--d-parch-dim)}
.d-pfield .d-err{font-size:12.5px;font-weight:600;color:var(--d-parch-red)}
.d-pfield .d-opt{font-style:normal;font-weight:500;opacity:.7}
.d-pfield.d-bad input,.d-pfield.d-bad select{border-color:#a3241a;box-shadow:inset 0 2px 6px rgba(0,0,0,.8),0 0 0 3px rgba(163,36,26,.25)}
.d-pcheck{display:flex;gap:9px;align-items:flex-start;font-size:13.5px;color:var(--d-parch-ink)}
.d-pcheck input{accent-color:var(--d-parch-red);width:16px;height:16px;margin:2px 0 0;flex:none}
.d-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-top:6px}
.d-code-input{letter-spacing:6px;font-variant-numeric:tabular-nums;text-align:center;font-weight:700!important}
.d-alert{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start;padding:13px 16px;margin:0 0 18px;border-radius:2px;font-size:14px;
  border:1px solid;background:rgba(255,255,255,.35)}
.d-alert::before{content:"";width:12px;height:12px;margin-top:5px;transform:rotate(45deg);background:currentColor;box-shadow:0 0 0 2px rgba(255,255,255,.6)}
.d-alert b{display:block}
.d-alert.d-ok{color:#245446;border-color:rgba(36,84,70,.45);background:rgba(78,140,122,.14)}
.d-alert.d-err{color:var(--d-parch-red);border-color:rgba(138,28,18,.45);background:rgba(158,36,20,.09)}
.d-alert.d-info{color:#5a3d12;border-color:rgba(138,112,27,.5);background:rgba(201,162,39,.14)}
.d-alert.d-warn{color:#7a3a0a;border-color:rgba(160,80,20,.5);background:rgba(216,69,31,.10)}
.d-chip{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:11px;font:700 11px var(--d-text);letter-spacing:.4px;text-transform:uppercase;
  color:var(--d-parch-ink);background:rgba(110,70,30,.15);border:1px solid rgba(110,70,30,.35)}
.d-chip.d-ok{color:#245446;background:rgba(78,140,122,.16);border-color:rgba(36,84,70,.4)}
.d-chip.d-err{color:var(--d-parch-red);background:rgba(158,36,20,.1);border-color:rgba(138,28,18,.4)}
.d-chip.d-gold{color:#5a3d12;background:rgba(201,162,39,.25);border-color:rgba(138,112,27,.5)}
.d-steps{display:flex;gap:0;margin:0 0 22px;counter-reset:s;list-style:none;padding:0}
.d-steps li{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;font:600 12px var(--d-text);color:var(--d-parch-dim);text-align:center}
.d-steps li::before{counter-increment:s;content:counter(s);display:grid;place-items:center;width:30px;height:30px;transform:rotate(45deg);font:700 13px var(--d-display);
  color:var(--d-parch-dim);background:#e8d4a4;border:2px solid rgba(110,70,30,.5);position:relative;z-index:1}
.d-steps li>*{transform:none}
.d-steps li::after{content:"";position:absolute;top:15px;left:calc(50% + 20px);right:calc(-50% + 20px);height:2px;background:rgba(110,70,30,.3)}
.d-steps li:last-child::after{display:none}
.d-steps li.d-on{color:var(--d-parch-red)}
.d-steps li.d-on::before{color:#ffe9c9;background:linear-gradient(#c33224,#7a0f0b);border-color:#3a0805;box-shadow:0 0 12px rgba(195,50,36,.45)}
.d-steps li.d-done::before{content:"✓";color:#2a1a04;background:linear-gradient(#f3d77c,#b8931f);border-color:#3a2606}
.d-steps li.d-done::after{background:var(--d-gold)}
.d-kv{display:grid;grid-template-columns:minmax(120px,auto) 1fr;gap:0;margin:0 0 16px;border-top:1px solid var(--d-parch-line)}
.d-kv dt,.d-kv dd{margin:0;padding:10px 8px;border-bottom:1px solid var(--d-parch-line)}
.d-kv dt{font-weight:700;color:var(--d-parch-dim);font-size:13px}
.d-kv dd{font-weight:600}
.d-tbl-wrap{overflow-x:auto;margin:0 0 16px;border:1px solid rgba(90,55,20,.45);box-shadow:0 1px 0 rgba(255,255,255,.4)}
.d-tbl{width:100%;border-collapse:collapse;font-size:14px;font-variant-numeric:tabular-nums}
.d-tbl th{position:sticky;top:0;padding:10px 12px;text-align:left;font:700 11.5px var(--d-display);letter-spacing:1.2px;text-transform:uppercase;color:#f6e7c4;
  background:linear-gradient(#5a3a1c,#3e2611);border-bottom:2px solid var(--d-gold)}
.d-tbl td{padding:10px 12px;border-bottom:1px solid var(--d-parch-line);white-space:nowrap}
.d-tbl tbody tr{transition:background .25s}
.d-tbl tbody tr:nth-child(even){background:rgba(110,70,30,.06)}
.d-tbl tbody tr:hover{background:rgba(201,162,39,.18)}
.d-tbl .d-num{text-align:right}
.d-tbl .d-rk{width:52px;text-align:center;font:700 15px var(--d-display);color:var(--d-parch-dim)}
.d-tbl tr:nth-child(1) .d-rk{color:#b8860b}
.d-tbl tr:nth-child(2) .d-rk{color:#7d8790}
.d-tbl tr:nth-child(3) .d-rk{color:#a0522d}
.d-tbl .d-me{background:rgba(201,162,39,.28)!important}
.d-pager{display:flex;gap:6px;justify-content:center;flex-wrap:wrap}
.d-pager a,.d-pager span{display:grid;place-items:center;min-width:36px;height:36px;padding:0 8px;font:700 13px var(--d-display);border:1px solid rgba(90,55,20,.45);color:var(--d-parch-ink);background:rgba(255,255,255,.25)}
.d-pager .d-on{color:#ffe9c9;background:linear-gradient(#c33224,#7a0f0b);border-color:#3a0805}
.d-seg{display:inline-flex;margin:0 0 16px;border:1px solid rgba(90,55,20,.55);border-radius:2px;overflow:hidden}
.d-seg a,.d-seg button{padding:8px 16px;font:700 12px var(--d-display);letter-spacing:1.3px;color:var(--d-parch-ink);background:rgba(255,255,255,.25);border:0;cursor:pointer}
.d-seg .d-on{color:#ffe9c9;background:linear-gradient(#c33224,#7a0f0b)}
.d-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px}
.d-card{position:relative;display:flex;flex-direction:column;overflow:hidden;color:var(--d-parch-ink);background:rgba(255,250,235,.45);border:1px solid rgba(90,55,20,.5);
  box-shadow:0 0 0 1px rgba(255,255,255,.4) inset,0 6px 14px rgba(60,30,10,.18);transition:transform .45s var(--d-ease),box-shadow .45s var(--d-ease)}
.d-card:hover{transform:translateY(-5px);box-shadow:0 0 0 1px var(--d-gold) inset,0 0 20px rgba(201,162,39,.35),0 14px 24px rgba(60,30,10,.3)}
.d-card .d-media{position:relative;display:grid;place-items:center;aspect-ratio:1;background:radial-gradient(circle at 50% 45%,#3b2616,#160d07 70%);border-bottom:2px solid #2a1808}
.d-card .d-media img{width:56%;image-rendering:pixelated;filter:drop-shadow(0 6px 10px rgba(0,0,0,.8));transition:transform .6s var(--d-ease)}
.d-card:hover .d-media img{transform:scale(1.12) rotate(-3deg)}
.d-card .d-body{display:grid;gap:4px;padding:12px 14px 14px}
.d-card .d-name{font:700 15px var(--d-display);color:var(--d-parch-ink)}
.d-card .d-price{font:700 15px var(--d-display);color:var(--d-parch-red);font-variant-numeric:tabular-nums}
.d-card .d-badge{position:absolute;top:8px;left:8px}
.d-ep{display:inline-flex;align-items:center;gap:5px}
.d-ep::before{content:"";width:12px;height:12px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#fff3b0,#d9ac3c 45%,#7a5a16);box-shadow:0 0 0 1px #3a2606}
.d-banner{position:relative;margin:0 0 26px;overflow:hidden;border:3px solid #2a1808;box-shadow:0 0 0 1px var(--d-gold),0 10px 24px rgba(60,30,10,.45)}
.d-banner img{display:block;width:100%;height:240px;object-fit:cover;transition:transform 1.2s var(--d-ease)}
.d-banner:hover img{transform:scale(1.04)}
.d-banner .d-cap{position:absolute;inset:auto 0 0 0;padding:40px 22px 16px;background:linear-gradient(transparent,rgba(10,5,3,.92))}
.d-banner b{display:block;font:900 26px/1.15 var(--d-deco);color:var(--d-ink);text-shadow:0 2px 8px #000}
.d-banner b span{color:var(--d-gold-hi)}
.d-banner p{margin:4px 0 0;color:var(--d-ink-dim);font-size:13.5px}
.d-notes{list-style:none;margin:0 0 6px;padding:0}
.d-notes li{display:grid;grid-template-columns:84px 1fr;gap:14px;padding:11px 8px;border-bottom:1px dashed var(--d-parch-line);transition:background .3s}
.d-notes li:hover{background:rgba(255,255,255,.22)}
.d-notes time{font:600 12px/1.25 var(--d-text);color:var(--d-parch-dim);font-variant-numeric:tabular-nums}
.d-notes time b{display:block;font:700 14px var(--d-display);color:var(--d-parch-red)}
.d-notes strong{font-weight:600}
.d-classes{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.d-cls{position:relative;display:block;overflow:hidden;border:2px solid #2a1808;box-shadow:0 0 0 1px rgba(201,162,39,.7),0 8px 18px rgba(60,30,10,.4);transition:transform .45s var(--d-ease),box-shadow .45s var(--d-ease)}
.d-cls img{display:block;width:100%;aspect-ratio:3/4;object-fit:cover;object-position:top;transition:transform .8s var(--d-ease),filter .5s}
.d-cls b{position:absolute;inset:auto 0 0;padding:26px 6px 9px;text-align:center;font:700 14px var(--d-display);letter-spacing:1.5px;color:var(--d-ink);background:linear-gradient(transparent,rgba(0,0,0,.92))}
.d-cls::after{content:"";position:absolute;inset:auto 0 0;height:3px;background:var(--d-c);box-shadow:0 0 12px var(--d-c)}
.d-cls:hover{transform:translateY(-6px);box-shadow:0 0 0 1px var(--d-gold-hi),0 0 22px rgba(246,219,122,.45),0 16px 26px rgba(60,30,10,.5)}
.d-cls:hover img{transform:scale(1.08);filter:saturate(1.15) brightness(1.05)}
.d-cta{display:flex;width:100%}
@media (max-width:760px){.d-classes{grid-template-columns:repeat(2,1fr)}
.d-parch{padding:22px 16px 34px}
.d-parch h1{font-size:23px}
.d-notes li{grid-template-columns:1fr;gap:2px}
.d-btn.d-big{--d-h:52px;padding:0 22px;font-size:14.5px;letter-spacing:2px}
.d-banner img{height:180px}
.d-banner b{font-size:20px}
.d-kv{grid-template-columns:1fr}
.d-kv dt{padding-bottom:0;border-bottom:0}
.d-steps li{font-size:11px}
.d-cards{grid-template-columns:repeat(2,1fr);gap:10px}}
.d-auth{display:grid;grid-template-columns:minmax(0,1fr);gap:30px;align-items:start}
.d-prow{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.d-pform .d-pnote{margin:0;font-size:13.5px;color:var(--d-parch-dim)}
.d-pform .d-pnote+.d-pnote{margin-top:-8px}
.d-pform .d-help{display:grid;gap:2px;margin:0;font-size:13.5px;color:var(--d-parch-dim)}
.d-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.d-msg{display:flex;flex-direction:column;align-items:center;text-align:center;padding-top:36px;padding-bottom:44px}
.d-msg .d-kicker{margin:0 0 18px;font:700 12px var(--d-display);letter-spacing:3.5px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-msg .d-mark{position:relative;display:grid;place-items:center;width:74px;height:74px;margin:0 0 22px}
.d-msg .d-mark::before{content:"";position:absolute;inset:10px;transform:rotate(45deg);border:2px solid #3a2606;
  background:linear-gradient(135deg,#f6e08f,#c9a227 50%,#8a6514);box-shadow:0 0 0 4px rgba(201,162,39,.25),0 8px 20px rgba(60,30,10,.45),inset 0 1px 0 rgba(255,255,255,.6)}
.d-msg .d-mark span{position:relative;top:3px;font:900 26px/1 var(--d-display);color:#2a1a04;text-shadow:0 1px 0 rgba(255,240,190,.6)}
.d-msg .d-mark.d-bad::before{border-color:#2a0503;background:linear-gradient(135deg,#e2533f,#9c1712 55%,#5c0907);box-shadow:0 0 0 4px rgba(158,36,20,.22),0 8px 20px rgba(60,30,10,.45),inset 0 1px 0 rgba(255,190,160,.5)}
.d-msg .d-mark.d-bad span{color:#ffe9c9;text-shadow:0 1px 2px #000}
.d-screen-in .d-msg .d-mark{animation:d-markin .7s var(--d-ease) both .1s}
@keyframes d-markin{from{opacity:0;transform:scale(.4) rotate(-90deg)}to{opacity:1;transform:none}}
.d-msg h1{margin:0 0 12px}
.d-msg{align-items:stretch}
.d-msg .d-mark{align-self:center}
.d-msg .d-body{margin:0 auto 24px;max-width:min(52ch,100%);font-size:15px;color:var(--d-parch-ink)}
.d-msg .d-actions{justify-content:center}
@media (max-width:1000px){.d-auth{grid-template-columns:minmax(0,1fr)}}
@media (max-width:760px){.d-prow{grid-template-columns:1fr}
.d-msg{padding-top:26px;padding-bottom:34px}
.d-msg .d-actions{flex-direction:column;align-items:stretch}
.d-pform .d-btn{width:100%}}
.d-kicker{margin:0 0 4px;font:700 11.5px var(--d-display);letter-spacing:2.5px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-acct-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;align-items:start}
.d-acct-grid>div{display:grid;grid-template-columns:minmax(0,1fr);gap:18px;min-width:0}
.d-pbox{position:relative;min-width:0;padding:16px 18px 18px;background:rgba(255,250,235,.42);border:1px solid rgba(90,55,20,.45);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.45),0 4px 12px rgba(60,30,10,.14)}
.d-pbox::before{content:"";position:absolute;top:-1px;left:16px;right:16px;height:2px;background:linear-gradient(90deg,transparent,var(--d-gold),transparent)}
.d-pbox h3{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 12px;font:900 15px var(--d-display);letter-spacing:1px;color:var(--d-parch-red)}
.d-pbox h3 a{font:600 12px var(--d-text);letter-spacing:0;color:var(--d-parch-dim)}
.d-pbox .d-kv{margin:0}
.d-pbox .d-note{margin:10px 0 0;font-size:13px;color:var(--d-parch-dim)}
.d-kv dd.d-ok{color:#245446}
.d-kv dd.d-warn{color:#8a4a0e}
.d-sbx{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:8px;margin:0;padding:10px 12px;background:rgba(78,140,122,.14);border:1px solid rgba(36,84,70,.35);color:#245446;font-weight:600}
.d-sbx strong{font:700 22px var(--d-display);font-variant-numeric:tabular-nums}
.d-pbox details{margin:0 0 10px}
.d-pbox details>summary{list-style:none;cursor:pointer}
.d-pbox details>summary::-webkit-details-marker{display:none}
.d-pbox details>summary .d-btn{pointer-events:none}
.d-pbox details[open]>summary .d-btn{filter:brightness(1.15)}
.d-pbox details .d-pform{margin:14px 0 6px;max-width:none;animation:rise .5s var(--d-ease) both}
.d-ep-big{margin:0;font:900 34px/1 var(--d-display);color:var(--d-parch-red);font-variant-numeric:tabular-nums}
.d-ep-big em{font:700 14px var(--d-display);font-style:normal;color:var(--d-parch-dim);margin-left:4px}
.d-ep-last{display:grid;gap:1px;margin:12px 0;padding:10px 12px;border-left:3px solid var(--d-gold);background:rgba(201,162,39,.12);font-size:13px}
.d-ep-last b{font:700 11px var(--d-display);letter-spacing:1.5px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-chars{list-style:none;margin:0;padding:0}
.d-chars li{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;padding:10px 4px;border-bottom:1px solid var(--d-parch-line)}
.d-chars .d-ic{width:38px;height:38px;border-radius:50%;background:#1a110b center/cover no-repeat;box-shadow:0 0 0 2px var(--d-c),0 0 0 3px #2a1808}
.d-chars .d-nm{display:block;font:700 15px var(--d-display);color:var(--d-parch-ink)}
.d-chars .d-meta{display:block;font-size:12.5px;color:var(--d-parch-dim)}
.d-chars .d-meta em{font-style:normal;font-weight:700;color:var(--d-c)}
.d-chars .d-lv{font:700 14px var(--d-display);color:var(--d-parch-red);white-space:nowrap}
.d-count{margin:0 0 6px;color:var(--d-parch-dim);font-size:13px}
.d-count strong{font:700 18px var(--d-display);color:var(--d-parch-ink)}
.d-tbl .d-tone-ok{color:#245446;font-weight:700}
.d-tbl .d-tone-bad{color:var(--d-parch-red);font-weight:700}
.d-tbl .d-tone-wait{color:#8a6a10;font-weight:700}
.d-shop-top{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:12px 20px;margin:0 0 18px}
.d-shop-top h1{margin:0}
.d-strip{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding:2px 0 4px;max-width:100%}
.d-strip::-webkit-scrollbar{display:none}
.d-strip a,.d-strip button{flex:none;display:inline-flex;align-items:center;height:34px;padding:0 14px;font:700 12px var(--d-display);letter-spacing:1.2px;color:var(--d-parch-ink);
  background:rgba(255,255,255,.3);border:1px solid rgba(90,55,20,.5);border-radius:17px;white-space:nowrap;transition:background .3s,color .3s;cursor:pointer}
.d-parch .d-strip a{font-weight:700;text-decoration:none}
.d-strip a:hover{background:rgba(201,162,39,.25)}
.d-strip a.d-on{color:#ffe9c9;background:linear-gradient(#c33224,#7a0f0b);border-color:#3a0805}
.d-strip .d-end{margin-left:6px;border-style:dashed}
.d-shelf-note{display:flex;gap:10px;margin:0 0 18px;padding:10px 14px;font-size:13px;color:var(--d-parch-dim);border:1px dashed rgba(110,70,30,.45);background:rgba(255,255,255,.18)}
.d-shelf-note b{color:var(--d-parch-red)}
.d-slot{position:relative;display:grid;place-items:center;aspect-ratio:1;background:
  radial-gradient(circle at 50% 45%,rgba(255,200,110,.18),transparent 60%),
  linear-gradient(135deg,#2c1d12,#120b06);
  box-shadow:inset 0 0 0 1px #000,inset 0 0 0 2px rgba(201,162,39,.55),inset 0 0 0 3px #000,inset 0 0 18px rgba(0,0,0,.8)}
.d-slot img{width:auto;height:64%;max-width:64%;image-rendering:pixelated;filter:drop-shadow(0 6px 8px rgba(0,0,0,.85));transition:transform .6s var(--d-ease)}
.d-slot .d-qty{position:absolute;right:8px;bottom:6px;font:700 13px var(--d-display);font-style:normal;color:#fff;text-shadow:0 1px 2px #000,0 0 4px #000}
.d-slot .d-flag{position:absolute;top:8px;left:8px}
.d-card .d-media{aspect-ratio:auto;display:block;background:none;border-bottom:2px solid #2a1808}
.d-card .d-media .d-slot{width:100%}
.d-card:hover .d-slot img{transform:scale(1.14) rotate(-3deg)}
.d-card .d-desc{font-size:12.5px;color:var(--d-parch-dim);line-height:1.4}
.d-card .d-cfoot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:6px}
.d-card .d-go{font:700 11px var(--d-display);letter-spacing:1.3px;text-transform:uppercase;color:#2a1a04;padding:5px 10px;border-radius:2px;
  background:linear-gradient(#fbe7a0,#c9a227);box-shadow:0 0 0 1px #3a2606}
.d-card.d-off{opacity:.62;filter:saturate(.5)}
.d-card.d-off .d-go{background:linear-gradient(#cfc2a4,#9a8b6a)}
.d-parch a.d-card{font-weight:400;text-decoration:none;color:var(--d-parch-ink)}
.d-price em,.d-prod .d-price em{font-style:normal;font-size:.8em;color:var(--d-parch-dim)}
.d-back{display:inline-flex;align-items:center;gap:6px;margin:0 0 16px;font-size:13.5px}
.d-back::before{content:"←"}
.d-prod{display:grid;grid-template-columns:220px 1fr;gap:28px;align-items:start}
.d-prod .d-slot{width:100%}
.d-prod .d-slot img{height:58%;max-width:58%}
.d-prod h1 .d-x{font-size:.7em;color:var(--d-parch-dim)}
.d-prod .d-price-row{display:flex;align-items:baseline;gap:12px;margin:6px 0 16px;padding:12px 14px;background:rgba(255,255,255,.3);border:1px solid rgba(90,55,20,.4)}
.d-prod .d-price-row span{font:700 12px var(--d-display);letter-spacing:1.5px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-prod .d-price-row strong{font:900 28px var(--d-display);color:var(--d-parch-red);font-variant-numeric:tabular-nums}
.d-prod .d-buy{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;margin:0 0 12px}
.d-prod .d-buy .d-pfield{width:110px}
.d-prod .d-bal{margin:0 0 8px;font-size:14px}
.d-prod .d-bal strong{font-variant-numeric:tabular-nums}
.d-conf{max-width:520px;margin:0 auto}
.d-conf-what{display:flex;align-items:center;gap:16px;margin:0 0 18px}
.d-conf-what .d-slot{width:84px;flex:none}
.d-conf-what .d-nm{font:700 18px var(--d-display);color:var(--d-parch-ink)}
.d-conf .d-kv dd{text-align:right;font-variant-numeric:tabular-nums}
.d-conf .d-kv .d-pay{font:900 20px var(--d-display);color:var(--d-parch-red)}
.d-conf .d-actions{margin:18px 0 12px}
.d-topup{max-width:460px;margin:0 auto;text-align:center}
.d-topup .d-h{margin:0;font:700 12px var(--d-display);letter-spacing:2px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-topup .d-n{margin:2px 0 14px;font:900 46px/1.05 var(--d-display);color:var(--d-parch-red);font-variant-numeric:tabular-nums}
.d-topup .d-n em{font-size:18px;font-style:normal;color:var(--d-parch-dim)}
.d-topup .d-added{display:inline-block;margin:0 0 16px;padding:8px 14px;color:#245446;background:rgba(78,140,122,.16);border:1px solid rgba(36,84,70,.4);font-weight:600}
.d-topup .d-pform{margin:0 auto 14px;text-align:left}
.d-topup .d-ways{display:flex;justify-content:center;gap:10px;font-size:13.5px}
.d-bill{list-style:none;margin:0 0 18px;padding:0;display:grid;gap:10px}
.d-slip{display:grid;grid-template-columns:64px 1fr auto;align-items:center;gap:16px;padding:10px 14px 10px 10px;background:rgba(255,250,235,.42);
  border:1px solid rgba(90,55,20,.45);box-shadow:inset 0 0 0 1px rgba(255,255,255,.4);transition:transform .35s var(--d-ease),box-shadow .35s var(--d-ease)}
.d-slip:hover{transform:translateX(4px);box-shadow:inset 0 0 0 1px var(--d-gold),0 6px 14px rgba(60,30,10,.18)}
.d-slip.d-new{animation:d-slipin 1s var(--d-ease) both;box-shadow:inset 0 0 0 1px var(--d-gold),0 0 18px rgba(201,162,39,.45)}
@keyframes d-slipin{from{opacity:0;transform:translateY(-14px) scale(.98)}to{opacity:1;transform:none}}
.d-slip .d-slot{width:64px}
.d-slip .d-nm{display:block;font:700 15px var(--d-display);color:var(--d-parch-ink)}
.d-slip .d-when{display:block;font-size:12.5px;color:var(--d-parch-dim);font-variant-numeric:tabular-nums}
.d-slip .d-end{display:grid;justify-items:end;gap:5px}
.d-slip .d-pr{font:700 15px var(--d-display);color:var(--d-parch-red);font-variant-numeric:tabular-nums}
.d-slip .d-pr em{font-style:normal;font-size:.8em;color:var(--d-parch-dim)}
.d-pgnav{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
.d-pgnav .d-pgbtn{display:inline-flex;align-items:center;height:36px;padding:0 14px;font:700 12px var(--d-display);letter-spacing:1px;border:1px solid rgba(90,55,20,.45);background:rgba(255,255,255,.25);color:var(--d-parch-ink)}
.d-pgnav .d-pgbtn[aria-disabled]{opacity:.45}
.d-pgnav .d-now{font-size:13px;color:var(--d-parch-dim);font-variant-numeric:tabular-nums}
@media (max-width:760px){.d-acct-grid{grid-template-columns:minmax(0,1fr)}
.d-prod{grid-template-columns:1fr;gap:16px}
.d-prod .d-slot{width:160px;margin:0 auto}
.d-slip{grid-template-columns:52px 1fr;gap:12px}
.d-slip .d-slot{width:52px}
.d-slip .d-end{grid-column:2;justify-items:start;grid-auto-flow:column;align-items:center;gap:10px}
.d-topup .d-n{font-size:38px}
.d-shop-top{align-items:stretch}
.d-strip{margin:0 -16px;padding:2px 16px 4px;max-width:none}
.d-conf-what .d-slot{width:64px}
.d-card .d-go{display:none}}
@media (max-width:980px){.d-acct-grid{grid-template-columns:minmax(0,1fr)}}
.d-shop-acts{display:flex;align-items:center;gap:10px}
.d-slot .d-flag.d-chip{font-style:normal;color:#2a1a04;background:linear-gradient(#f6dc85,#c9a227);border-color:#3a2606;box-shadow:0 2px 6px rgba(0,0,0,.6)}
.d-acct-grid{grid-template-columns:minmax(0,1fr)}
@media (min-width:761px){.d-prod{grid-template-columns:180px 1fr;gap:22px}}
.d-card .d-cfoot .d-btn{white-space:nowrap;padding:0 10px}
.d-acct .d-bal{gap:8px}
.d-acct .d-bal span{min-width:0}
.d-acct .d-bal b{font-size:18px;white-space:nowrap}
.d-parch .d-eyebrow{margin:0 0 4px;font:700 11.5px var(--d-display);letter-spacing:2.5px;text-transform:uppercase;color:var(--d-parch-dim)}
.d-actions.d-center{justify-content:center;margin-top:26px}
.d-parch .d-back{margin:0 0 14px;font-size:13.5px}
.d-dl-hero{display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;margin:0 0 6px;padding:18px 20px;
  background:linear-gradient(rgba(42,24,8,.88),rgba(26,15,6,.92));border:1px solid #2a1808;box-shadow:0 0 0 1px rgba(201,162,39,.6),inset 0 0 30px rgba(0,0,0,.5)}
.d-dl-hero .d-small{margin:0;color:var(--d-ink-dim)}
.d-dl-hero .d-btn svg{flex:none;animation:bob 1.8s var(--d-ease) infinite}
.d-how{list-style:none;margin:0 0 6px;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;counter-reset:h}
.d-how li{position:relative;padding:14px 16px 12px 60px;background:rgba(255,250,235,.4);border:1px solid rgba(90,55,20,.4);min-width:0}
.d-how li::before{counter-increment:h;content:counter(h);position:absolute;left:16px;top:16px;display:grid;place-items:center;width:32px;height:32px;clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);
  font:700 13px var(--d-display);color:#ffe9c9;background:linear-gradient(#c33224,#7a0f0b)}
.d-how li h3{margin:0 0 4px}
.d-how li p{margin:0 0 3px}
.d-src-list{display:grid;gap:8px;margin:0 0 6px}
.d-src{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;background:rgba(255,250,235,.4);border:1px solid rgba(90,55,20,.4)}
.d-src>span{display:grid;min-width:0}
.d-src>span span{font-size:13px;color:var(--d-parch-dim)}
.d-dl-two{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:20px;margin-top:22px}
.d-dl-two h3{margin-top:0}
.d-aside-box{padding:16px 18px;background:rgba(138,28,18,.07);border:1px solid rgba(138,28,18,.3)}
.d-aside-box p{font-size:14px}
.d-podium{list-style:none;display:grid;grid-template-columns:1fr 1.15fr 1fr;align-items:end;gap:12px;margin:0 0 20px;padding:0}
.d-pod{position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:16px 10px 14px;text-align:center;min-width:0;
  background:linear-gradient(rgba(42,24,8,.9),rgba(22,13,6,.95));border:1px solid #2a1808;color:var(--d-ink);
  box-shadow:0 0 0 1px rgba(201,162,39,.55),inset 0 -40px 50px -30px var(--d-c),0 10px 20px rgba(60,30,10,.35);transition:transform .45s var(--d-ease)}
.d-pod:hover{transform:translateY(-5px)}
.d-pod-1{padding-top:22px;padding-bottom:20px;box-shadow:0 0 0 1px var(--d-gold-hi),0 0 24px rgba(227,190,74,.35),inset 0 -40px 50px -30px var(--d-c),0 12px 24px rgba(60,30,10,.4)}
.d-pod img{width:64px;height:64px;border-radius:50%;object-fit:cover;object-position:top;border:2px solid var(--d-c);box-shadow:0 0 0 2px #000,0 0 14px var(--d-c)}
.d-pod-1 img{width:84px;height:84px}
.d-pod strong{margin-top:6px;font:700 15px var(--d-display);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.d-pod-cls{font-size:12px;color:var(--d-c)}
.d-pod-meta{font-size:12px;color:var(--d-ink-dim)}
.d-pod-pos{position:absolute;top:-14px;left:50%;margin-left:-17px;top:-17px;display:grid;place-items:center;width:34px;height:34px;clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%);
  font:900 14px var(--d-display);color:#2a1a04;background:linear-gradient(#f3d77c,#b8931f);filter:drop-shadow(0 0 1px #000)}
.d-pod-2 .d-pod-pos{background:linear-gradient(#f1f3f5,#9aa3ab)}
.d-pod-3 .d-pod-pos{background:linear-gradient(#f0b98a,#9a5a2a)}
.d-rank-tbl .d-rk-who{display:inline-flex;align-items:center;gap:8px}
.d-rank-tbl .d-rk-flag{width:20px;height:20px;object-fit:contain}
.d-rank-tbl .d-rk-face{width:28px;height:28px;border-radius:50%;object-fit:cover;object-position:top;border:1px solid rgba(58,36,19,.6)}
.d-rank-tbl th.d-num{text-align:right}
.d-parch .d-dash{color:var(--d-parch-dim)}
.d-tbl tbody tr.d-me td{font-weight:700}
.d-parch .d-pager{margin-top:6px}
.d-parch .d-seg{max-width:100%;overflow-x:auto}
.d-parch .d-seg a{white-space:nowrap;text-decoration:none!important}
.d-parch .d-pager a{font-weight:700;text-decoration:none}
.d-newslist{list-style:none;margin:0 0 18px;padding:0}
.d-newsrow{padding:16px 6px;border-bottom:1px dashed var(--d-parch-line);transition:background .3s}
.d-newsrow:hover{background:rgba(255,255,255,.2)}
.d-nmeta{display:flex;align-items:center;gap:10px;margin:0 0 6px!important;font-size:12.5px;color:var(--d-parch-dim)}
.d-newsrow h3{margin:0 0 6px;font-size:16.5px;line-height:1.35}
.d-newsrow h3 a{color:var(--d-parch-ink)}
.d-newsrow h3 a:hover{color:var(--d-parch-red)}
.d-newsrow p{margin:0 0 6px}
.d-more-link{font-size:13px}
.d-post h1{margin-bottom:16px}
.d-post-body .d-alert{max-width:none}
.d-nf .d-parch{text-align:center;padding-top:36px}
.d-nf .d-parch p{margin-left:auto;margin-right:auto}
.d-nf-code{margin:0;font:900 96px/1 var(--d-deco);color:transparent;
  background:linear-gradient(#e2bb4c,#8a1c12);-webkit-background-clip:text;background-clip:text;filter:drop-shadow(0 3px 0 rgba(58,36,19,.35))}
.d-nf .d-actions{justify-content:center}
.d-cls-nav{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin:0 0 10px}
.d-cls-nav a{display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 6px;text-align:center;font:700 13px var(--d-display);letter-spacing:1px;color:var(--d-parch-ink);
  background:rgba(255,250,235,.4);border:1px solid rgba(90,55,20,.4);border-bottom:3px solid var(--d-c);transition:transform .35s var(--d-ease),box-shadow .35s}
.d-cls-nav a:hover{transform:translateY(-3px);text-decoration:none;box-shadow:0 8px 16px rgba(60,30,10,.25)}
.d-cls-nav img{width:54px;height:54px;border-radius:50%;object-fit:cover;object-position:top;border:2px solid var(--d-c)}
.d-cls-sec{padding:26px 0 8px;border-top:1px solid var(--d-parch-line);margin-top:22px;scroll-margin-top:70px}
.d-cls-top{display:grid;grid-template-columns:190px minmax(0,1fr);gap:22px;align-items:start}
.d-cls-art{width:100%;aspect-ratio:3/4;object-fit:cover;object-position:top;border:3px solid #2a1808;box-shadow:0 0 0 1px var(--d-gold),0 0 0 4px var(--d-c),0 10px 22px rgba(60,30,10,.4)}
.d-cls-sec h2{margin-top:0;color:var(--d-parch-ink);font-size:24px}
.d-cls-sec h2::after{background:linear-gradient(90deg,var(--d-c),transparent)}
.d-cls-tactic{font:700 13px var(--d-display)!important;letter-spacing:1.2px;text-transform:uppercase;color:var(--d-parch-red)}
.d-paths{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.d-path{padding:14px 16px;background:rgba(255,250,235,.4);border:1px solid rgba(90,55,20,.4);border-top:3px solid var(--d-c);min-width:0}
.d-path h4{margin:0 0 8px;font:700 14px var(--d-display);letter-spacing:1.5px;text-transform:uppercase;color:var(--d-parch-red)}
.d-skills{margin:0}
.d-skills dt{margin-top:9px;font-weight:700;color:var(--d-parch-ink)}
.d-skills dt:first-child{margin-top:0}
.d-skills dd{margin:1px 0 0;font-size:13.5px;color:var(--d-parch-ink)}
.d-skills .d-tier{display:block;font-size:12px;color:var(--d-parch-dim);font-style:italic}
.d-legal{display:grid;grid-template-columns:200px minmax(0,1fr);gap:26px}
.d-docnav{display:grid;align-content:start;gap:4px;position:sticky;top:76px}
.d-docnav a{padding:9px 12px;font-weight:600;color:var(--d-parch-ink);border-left:3px solid transparent;background:rgba(255,250,235,.3);text-decoration:none!important}
.d-docnav a:hover{border-left-color:var(--d-gold)}
.d-docnav a.d-on{color:var(--d-parch-red);border-left-color:var(--d-parch-red);background:rgba(255,250,235,.6)}
.d-doc .d-upd{margin-bottom:14px}
.d-doc h2{font-size:16px}
@media (max-width:760px){.d-how{grid-template-columns:1fr}
.d-src{flex-wrap:wrap}
.d-dl-two{grid-template-columns:1fr}
.d-dl-hero{flex-direction:column;align-items:stretch;text-align:center}
.d-podium{gap:6px}
.d-pod{padding:14px 4px 10px}
.d-pod img{width:46px;height:46px}
.d-pod-1 img{width:58px;height:58px}
.d-pod strong{font-size:12.5px}
.d-cls-nav{grid-template-columns:repeat(2,minmax(0,1fr))}
.d-cls-top{grid-template-columns:1fr}
.d-cls-art{max-width:220px;margin:0 auto}
.d-paths{grid-template-columns:1fr}
.d-legal{grid-template-columns:1fr;gap:16px}
.d-docnav{position:static;grid-template-columns:1fr 1fr}
.d-nf-code{font-size:72px}}
.d-parch h1{font-size:30px}
.d-parch h2,.d-ftitle{font-size:20px}
.d-btn{font-size:15px}
.d-btn.d-big{font-size:18px}
.d-seg a,.d-seg button,.d-tab{font-size:14px}
.ch-warrior{--d-c:var(--d-c-warrior)}.ch-assassin{--d-c:var(--d-c-assassin)}.ch-sura{--d-c:var(--d-c-sura)}.ch-shaman{--d-c:var(--d-c-shaman)}

/* zz-port.css */
/* ============================================================================
   PORT FIXES -- the few places where the real markup differs from the
   design preview's in a way the generated zd.css cannot know about (an <img>
   carrying width/height attributes for layout stability, a form the real flow
   draws that the preview did not). Kept apart from zd.css so that file stays
   a pure, regenerable copy of the design.
   ========================================================================= */
.d-cls img, .d-banner img { height: auto; }
/* The front page's opening when signed in or during maintenance: the design
   only drew the signed-out banner, so these take the sheet's own rhythm. */
.d-head { margin: 0 0 26px; }
.d-head .d-actions { margin-block-start: 14px; }
/* A patch-note headline links to its post; it keeps the line's own ink. */
.d-note-link { color: inherit !important; font-weight: inherit !important; text-decoration: none; }
.d-note-link:hover { text-decoration: underline; }
.d-text { white-space: pre-line; }
.d-cls-art { height: auto; }
/* The ranking tabs are two radio labels (no script) drawn as the design's
   segmented control; the checked radio marks its label. */
.d-seg label { padding: 8px 16px; font: 14px var(--f-portal); color: var(--d-parch-ink); background: rgba(255,255,255,.25); cursor: pointer; white-space: nowrap; }
#rank-players:checked ~ .d-seg [for="rank-players"],
#rank-guilds:checked ~ .d-seg [for="rank-guilds"] { color: #ffe9c9; background: linear-gradient(#c33224, #7a0f0b); }
/* An empty slot the size of a flag, so a kingdomless name lines up. */
.d-rk-slot { display: inline-flex; inline-size: 20px; justify-content: center; }
/* The design set these few spacings inline; the site carries no style
   attributes, so they are named here. */
.d-acct-top { margin-top: 18px; }
.d-note-lead { margin: 0 0 12px; }
.d-note-top { margin-top: 6px; }
.d-flush { margin: 0; }
/* A character's portrait comes from its class slug -- no inline style, and a
   job the site cannot place draws an empty disc rather than a wrong face. */
.d-ch.ch-warrior .d-ic { background-image: url("/assets/img/class-warrior-face.fff66f81.webp"); }
.d-ch.ch-assassin .d-ic { background-image: url("/assets/img/class-assassin-face.738b4a68.webp"); }
.d-ch.ch-sura .d-ic { background-image: url("/assets/img/class-sura-face.a2347a6a.webp"); }
.d-ch.ch-shaman .d-ic { background-image: url("/assets/img/class-shaman-face.fa4fe799.webp"); }
.d-body-end { margin-top: 20px; margin-bottom: 0; }
/* The shelf's balance and top-up, kept beside the title (see shop.html). */
.d-purse { display: flex; align-items: center; gap: 12px; color: var(--d-parch-dim); font-size: 14px; }
.d-purse b { color: var(--d-parch-red); font: 18px var(--f-portal); font-variant-numeric: tabular-nums; }
.d-strip-top { margin: 0 0 20px; }
/* A POST that reads as a link (it mints a one-time ticket, so it cannot be
   one): the ink and underline of the parchment's links. */
.d-linkbtn { padding: 0; border: 0; background: none; cursor: pointer; font: inherit; font-weight: 600; color: var(--d-parch-red); text-decoration: underline; }
.d-left { text-align: left; }

/* EVERY PAGE IS THREE COLUMNS (Baran, 2026-10-06), so the shop shelf sits in
   the ~640px centre: three cards a row, as in the design's
   `.col-mid .cards` rule (which the generator skips because it names the
   preview's column class). */
@media (min-width: 761px) {
	.pt-mid .d-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
}
.d-card .d-cfoot .d-go { white-space: nowrap; }

/* THE ACCOUNT'S NUMBERS ON PARCHMENT. The tiles' base colours are the dark
   site's (light ink on wood); on the welcome sheet they came out near-white on
   light paper and could not be read (Baran, 2026-10-06). Parchment inks here. */
.d-parch .tiles dt { color: var(--d-parch-dim); }
.d-parch .tiles dd { color: var(--d-parch-ink); font-weight: 700; }
.d-parch .tiles dd small { color: var(--d-parch-dim); }
