/*
Theme Name:        Axismundi
Theme URI:         https://github.com/Jiwoon-Kim/axismundi/tree/main/products/distributables/themes/axismundi
Author:            KIM JIWOON
Author URI:        https://designbusan.ai.kr
Description:       Axismundi is a standalone Material Design 3 block theme for WordPress. It binds native WordPress core blocks to a Material-token design language (color, typography, shape, motion, elevation) and is built toward an ActivityPub-based social CMS.
Requires at least: 7.0
Tested up to:      7.0
Requires PHP:      8.1
Version:           0.1.3
License:           GPL-3.0-or-later
License URI:       https://www.gnu.org/licenses/gpl-3.0.html
Text Domain:       axismundi
Tags:              block-patterns, custom-colors, custom-logo, editor-style
*/

/* ============================================================
 * Global HTML semantic glue.
 *
 * Enqueued on the front (functions.php) and mirrored into the editor canvas
 * (add_editor_style). Kept intentionally tiny: document-wide baselines for raw
 * standard HTML elements that can arrive from any source (Custom HTML block,
 * markdown, federated content). Block-specific pseudo / specificity fixes live
 * in assets/styles/blocks.text.css; component styling in components.*.css.
 * Rendering only — authoring tools (e.g. a <mark> toolbar format, an <abbr>
 * title editor) are a separate RichText plugin concern.
 * ============================================================ */

/* Smooth in-page anchor scrolling — TOC links, hash navigation, "back to top".
 * This is document-wide UX owned by the theme, not any single block, so a TOC
 * plugin must not preventDefault + scroll to own it. Disabled under reduced motion.
 * scroll-behavior applies to the scroll container, which for the page is :root. */
:root {
	scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
	:root {
		scroll-behavior: auto;
	}
}

/* Anchor landing offset for in-content headings. A clicked TOC link (or any hash
 * jump) lands the heading 15% down the viewport — intentionally a touch above the
 * TOC scroll-spy active line (axismundi/toc view.js, innerHeight * 0.2), so a
 * clicked heading settles just above the line, which reads better. :where() keeps
 * specificity at 0 so a block-level scroll-margin override still wins. */
:where(.wp-block-post-content) :is(h2, h3, h4, h5, h6) {
	scroll-margin-top: 15vh;
}

/* Mixed-script wrapping: Korean stays word-grouped while long Latin tokens,
 * URLs, and handles can still break safely on narrow viewports. */
body {
	word-break: keep-all;
	overflow-wrap: anywhere;
}

/* Content lists — front-end query templates render posts inside
 * `ul.wp-block-post-template > li`, which makes browser UA rules treat the
 * first content list as a nested `ul`. Reset marker depth at post-content root. */
ul.wp-block-list:not([class*="is-style-"]) {
	list-style-type: disc;
}
ul.wp-block-list:not([class*="is-style-"]) ul {
	list-style-type: circle;
}
ul.wp-block-list:not([class*="is-style-"]) ul ul {
	list-style-type: square;
}

/* <mark> — highlight. M3 tertiary-container by default; :not([style]) so the
 * WordPress Highlight format's user-chosen inline colour is never overridden. */
mark:not([style]) {
	background-color: var(--wp--preset--color--tertiary-container);
	color: var(--wp--preset--color--on-tertiary-container);
	padding-inline: 0.2em;
	border-radius: 4px;
}

/* <abbr title> — dotted underline + help cursor (the title is the affordance). */
abbr[title] {
	text-decoration: underline dotted;
	text-decoration-skip-ink: auto;
	text-underline-offset: 2px;
	cursor: help;
}

/* <details>/<summary> — disclosure surface for raw HTML, Custom HTML, and
 * attachment metadata. The core/details block mirrors these tokens in
 * theme.json so the Site Editor controls and Stylebook stay in sync. */
details {
	box-sizing: border-box;
	border: 1px solid var(--wp--preset--color--outline-variant);
	border-radius: 8px;
	background-color: var(--wp--preset--color--surface-container-low);
	color: var(--wp--preset--color--on-surface);
}
details[open] {
	padding-block-end: var(--wp--preset--spacing--200);
}
details[open]:has(> pre:last-child) {
	padding-block-end: 0;
}
details > summary {
	cursor: pointer;
	padding: var(--wp--preset--spacing--150) var(--wp--preset--spacing--200);
	color: var(--wp--preset--color--on-surface-variant);
	font-weight: 500;
}
details > :not(summary) {
	margin-inline: var(--wp--preset--spacing--200);
}
details > summary + *,
.wp-block-details > summary + * {
	margin-block-start: 0;
}
details > :last-child {
	margin-block-end: 0;
}
details > pre,
details > pre.wp-block-code,
details > pre.wp-block-preformatted,
details > pre:not([class*="wp-block"]) {
	margin: 0;
	margin-inline: 0;
	padding: var(--wp--preset--spacing--200);
	border-start-start-radius: 0;
	border-start-end-radius: 0;
	border-end-start-radius: 8px;
	border-end-end-radius: 8px;
	background-color: var(--wp--preset--color--surface-container-high);
}

/* <figcaption> / <caption> — standard caption semantics for raw figures and
 * tables. WordPress' `elements.caption` styles `.wp-element-caption`, but raw
 * HTML captions from Custom HTML / markdown need the same baseline here. */
figcaption,
caption {
	color: var(--wp--preset--color--on-surface-variant);
	font-size: var(--wp--preset--font-size--body-small);
	line-height: 1.333;
	letter-spacing: 0.4px;
	text-align: center;
}
figcaption {
	margin-block-start: var(--wp--preset--spacing--100);
}
caption {
	caption-side: bottom;
	margin-block-start: var(--wp--preset--spacing--100);
}

/* <hr> / core/separator — M3 divider: a 1dp full-width line in outline-variant
 * (m3.material.io/components/divider/specs). One baseline drives both the raw
 * <hr> and core/separator, which renders <hr class="wp-block-separator"> — so
 * the separator no longer needs its own theme.json css. Core forces
 * border-top:2px on the block class, so border:0 + the class match here override
 * it; is-style-dots keeps its decorative core styling.
 *
 * The line is a content-box-clipped background, not a border, so the inset /
 * middle-inset variations can shrink the visible line with padding while the
 * element box stays full-width. That matters because the block editor centres
 * each block (max-width + margin:auto); margin/width-based insets get swallowed
 * by that centring (line stays full-width in the canvas), but padding on a
 * full-width box insets the painted line identically on the front and in the
 * editor. */
hr,
.wp-block-separator:not(.is-style-dots) {
	box-sizing: border-box;
	border: 0;
	block-size: 1px;
	background-color: var(--wp--preset--color--outline-variant);
	background-clip: content-box;
}

/* Media — keep raw img / picture / video / audio / iframe / embeds within the
 * content column on narrow viewports. Core media blocks are already responsive,
 * but Custom HTML / markdown / federated media arrive without those wrappers and
 * otherwise overflow horizontally. max-width:100% only constrains oversized
 * media, so small icons/images are untouched; height:auto keeps the aspect ratio
 * of images and video as they scale down. */
img,
picture,
video,
audio,
iframe,
embed,
object,
svg,
canvas {
	max-width: 100%;
	box-sizing: border-box;
}
img,
video {
	height: auto;
}
/* Block-level replaced media — <video>/<audio>/<iframe>/<embed>/<object> are
 * inline replaced elements by default, so the constrained layout's
 * margin-inline:auto can't centre them: bare (Custom HTML / markdown / federated)
 * media left-aligns in a wide content column while block siblings (<figure>,
 * <p>) centre correctly. Promote them to block so they sit in the content column
 * like everything else. <img>/<picture>/<svg> are deliberately left inline so
 * inline images in prose stay inline; block images arrive wrapped in <figure>. */
video,
audio,
iframe,
embed,
object {
	display: block;
	margin-inline: auto;
}
/* Avatars carry explicit width/height attributes and are a fixed size; opt them
 * out of the blanket shrink-to-fit above so a wide flex sibling (a long comment
 * body, a byline row) cannot squeeze the avatar below its size. TT5 ships no
 * blanket img rule so its avatars never hit this; ours does (for unwrapped
 * federated/markdown media), hence this targeted exception. */
.wp-block-avatar {
	flex-shrink: 0;
}
/* Native <audio>/<video> controls render inside a UA shadow DOM that page CSS
 * cannot reach, so color-scheme is the only real lever: it makes the browser
 * paint the controls in its dark or light skin to match the active theme.
 * accent-color is deliberately NOT set — it tints form controls (range,
 * checkbox, progress) but is ignored by media controls in current browsers, so
 * setting it here would be a misleading no-op. A fully M3-styled player would
 * need a custom JS player, which is out of scope for the theme. */
audio,
video {
	color-scheme: inherit;
}

/* iframe canvas — color-scheme on :root (set above for the native controls)
 * makes an iframe paint an OPAQUE Canvas background, which shows as a white box
 * behind transparent embeds and srcdoc content (a regression once the root
 * color-scheme landed; before it, iframe canvases were transparent). Opt iframes
 * back out with color-scheme:normal so the canvas is transparent again and the
 * embed shows on the page background. The embedded document keeps its own
 * scheme; only the iframe's backdrop is affected. */
iframe {
	color-scheme: normal;
}

/* WordPress image lightbox — core paints the backdrop as the global surface at
 * high opacity, which is a near-white canvas in light mode. Use the M3
 * scheme-neutral scrim (neutral-0) instead, with a stronger viewer dim.
 *
 * Two core behaviours force the exact form here:
 *  - The color is written as an inline style on .scrim, so background-color
 *    needs !important to win.
 *  - The `.scrim` opacity is driven by core's turn-on-visibility animation
 *    (forwards), which lands on opacity:1 and overrides any opacity declaration.
 * So the dim is baked into the color's alpha via color-mix rather than set
 * with `opacity`; the fade-in animation still plays. */
.wp-lightbox-overlay .scrim {
	background-color: color-mix(in srgb, var(--md-sys-color-scrim) 72%, transparent) !important;
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button) {
	box-sizing: border-box;
	padding: 0;
	border-radius: 9999px;
	background-color: transparent;
	color: #fff !important;
	fill: currentColor !important;
	transition:
		border-radius var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
		background-color var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
}
.wp-lightbox-overlay .wp-lightbox-close-button {
	inline-size: 40px;
	block-size: 40px;
	padding: var(--wp--preset--spacing--100) !important;
}
.wp-lightbox-overlay .wp-lightbox-navigation-button {
	inline-size: 48px;
	block-size: 48px;
	padding: var(--wp--preset--spacing--100) !important;
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button):has(
		:where(.wp-lightbox-close-text, .wp-lightbox-navigation-text):not([hidden])
	) {
	min-inline-size: 40px;
	inline-size: max-content;
	gap: var(--wp--preset--spacing--100);
	padding-inline: var(--wp--preset--spacing--200) !important;
	font-size: var(--wp--preset--font-size--label-large);
	font-weight: 500;
	line-height: 1.429;
	letter-spacing: 0.1px;
}
.wp-lightbox-overlay .wp-lightbox-navigation-button:has(.wp-lightbox-navigation-text:not([hidden])) {
	min-inline-size: 48px;
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button):hover {
	/* !important: core sets `.wp-lightbox-overlay .wp-lightbox-…-button:hover
	 * { background: none }` at (0,3,0), which our :where() rule (0,2,0) cannot
	 * beat — so the state layer needs !important, like the scrim above. */
	background-color: color-mix(in srgb, currentColor calc(var(--md-sys-state-hover-state-layer-opacity) * 100%), transparent) !important;
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button):focus {
	background-color: color-mix(in srgb, currentColor calc(var(--md-sys-state-focus-state-layer-opacity) * 100%), transparent) !important;
	outline: 3px solid currentColor;
	outline-offset: 2px;
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button):active {
	border-radius: 8px;
	background-color: color-mix(in srgb, currentColor calc(var(--md-sys-state-pressed-state-layer-opacity) * 100%), transparent) !important;
}
.wp-lightbox-overlay .wp-lightbox-close-icon,
.wp-lightbox-overlay .wp-lightbox-navigation-icon {
	--md-icon-fill: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 1em;
	block-size: 1em;
	overflow: hidden;
	color: #fff;
	font-size: var(--md-icon-size, 24px);
}
.wp-lightbox-overlay :where(.wp-lightbox-close-button, .wp-lightbox-navigation-button):is(:hover, :focus, :active)
	:where(.wp-lightbox-close-icon, .wp-lightbox-navigation-icon) {
	--md-icon-fill: 1;
}
.wp-lightbox-overlay .wp-lightbox-close-icon svg,
.wp-lightbox-overlay .wp-lightbox-navigation-icon svg {
	display: none !important;
}
.wp-lightbox-overlay .wp-lightbox-close-icon::before,
.wp-lightbox-overlay .wp-lightbox-navigation-icon::before {
	font-family: "Material Symbols Outlined", sans-serif;
	font-weight: normal;
	font-style: normal;
	font-size: 1em;
	line-height: 1;
	letter-spacing: normal;
	text-transform: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 1em;
	block-size: 1em;
	overflow: hidden;
	white-space: nowrap;
	direction: ltr;
	-webkit-font-feature-settings: "liga";
	font-feature-settings: "liga";
	-webkit-font-smoothing: antialiased;
	font-variation-settings:
		"FILL" var(--md-icon-fill, 0),
		"wght" var(--md-icon-wght, 400),
		"GRAD" var(--md-icon-grad, 0),
		"opsz" var(--md-icon-opsz, 24);
	transition: --md-icon-fill var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));
}
.wp-lightbox-overlay .wp-lightbox-close-icon {
	--md-icon-size: 24px;
}
.wp-lightbox-overlay .wp-lightbox-close-icon::before {
	content: "\e5cd"; /* Material Symbols: close */
}
.wp-lightbox-overlay .wp-lightbox-navigation-icon {
	--md-icon-size: 32px;
}
.wp-lightbox-overlay .wp-lightbox-navigation-button-prev .wp-lightbox-navigation-icon::before {
	content: "\e5cb"; /* Material Symbols: chevron_left */
}
.wp-lightbox-overlay .wp-lightbox-navigation-button-next .wp-lightbox-navigation-icon::before {
	content: "\e5cc"; /* Material Symbols: chevron_right */
}

/* Raw <table> — Custom HTML / markdown / federated content. Core/table exposes
 * its editable source in theme.json and gets WordPress-specific resets in
 * blocks.table.css; this global semantic baseline is for ordinary HTML tables
 * that arrive without a block wrapper. */
table {
	box-sizing: border-box;
	inline-size: 100%;
	border-collapse: separate;
	border-spacing: 0;
	border: 1px solid var(--wp--preset--color--outline-variant);
	border-radius: 8px;
	color: var(--wp--preset--color--on-surface);
	font-size: var(--wp--preset--font-size--body-medium);
	line-height: 1.429;
	letter-spacing: 0.25px;
}
:where(th, td) {
	box-sizing: border-box;
	background-clip: padding-box;
	text-align: start;
	vertical-align: top;
	padding-block: var(--wp--preset--spacing--150);
	padding-inline: var(--wp--preset--spacing--200);
	border: 0;
	border-block-end: 1px solid var(--wp--preset--color--outline-variant);
	border-inline-end: 1px solid var(--wp--preset--color--outline-variant);
}
th {
	background-color: var(--wp--preset--color--surface-container-high);
	font-weight: 500;
}
tr > :where(th, td):last-child {
	border-inline-end: 0;
}
tbody tr:last-child > :where(th, td) {
	border-block-end: 0;
}
thead :where(th, td) {
	border-block-end: 1px solid var(--wp--preset--color--outline);
}
thead tr:first-child > :where(th, td):first-child {
	border-start-start-radius: 7px;
}
thead tr:first-child > :where(th, td):last-child {
	border-start-end-radius: 7px;
}
tfoot tr:first-child > :where(th, td) {
	border-block-start: 1px solid var(--wp--preset--color--outline);
}
tfoot tr:last-child > :where(th, td) {
	border-block-end: 0;
}

/* Raw <blockquote> — match core/quote's emphasis bar for Custom HTML,
 * markdown, and federated content without touching pullquote's nested quote. */
blockquote:not([class*="wp-block"]):not(.wp-block-pullquote blockquote) {
	margin-inline: 0;
	padding-block: var(--wp--preset--spacing--100);
	padding-inline-start: var(--wp--preset--spacing--300);
	border-inline-start: 4px solid var(--wp--preset--color--primary);
	color: var(--wp--preset--color--on-surface);
}
blockquote:not([class*="wp-block"]):not(.wp-block-pullquote blockquote) > p {
	margin-block: 0;
	color: inherit;
}
blockquote:not([class*="wp-block"]):not(.wp-block-pullquote blockquote) cite {
	display: block;
	margin-block-start: var(--wp--preset--spacing--100);
	color: var(--wp--preset--color--on-surface-variant);
	font-size: var(--wp--preset--font-size--body-small);
	font-style: normal;
	font-weight: 400;
	line-height: 1.333;
	letter-spacing: 0.4px;
}

/* Text selection — global document affordance. */
::selection {
	background-color: var(--wp--preset--color--secondary-container);
	color: var(--wp--preset--color--on-secondary-container);
}

/* <code> — Roboto Mono everywhere; inline code (NOT inside <pre>) gets a small
 * surface-container pill. The core/code + core/preformatted blocks own their own
 * block layout, so `pre code` resets the inline pill back to flat. */
code {
	font-family: var(--wp--preset--font-family--roboto-mono);
}
:not(pre) > code {
	font-size: var(--wp--preset--font-size--body-medium);
	padding-inline: 0.3em;
	padding-block: 0.15em;
	border-radius: 4px;
	background-color: var(--wp--preset--color--surface-container);
	color: var(--wp--preset--color--on-surface);
}
pre code {
	padding: 0;
	border-radius: 0;
	background-color: transparent;
	color: inherit;
	font-size: inherit;
}

/* Raw <pre> — Custom HTML / markdown code blocks get the same mono card as
 * core/code and core/preformatted. Core blocks own their surface in theme.json
 * so Global Styles controls and Stylebook previews remain editable. */
pre:not([class*="wp-block"]) {
	display: block;
	overflow-x: auto;
	padding: var(--wp--preset--spacing--300);
	border-radius: 8px;
	background-color: var(--wp--preset--color--surface-container);
	color: var(--wp--preset--color--on-surface);
	font-family: var(--wp--preset--font-family--roboto-mono);
	font-size: var(--wp--preset--font-size--body-medium);
	tab-size: 2;
	scrollbar-width: thin;
	scrollbar-color: var(--wp--preset--color--outline-variant) transparent;
}
pre:not([class*="wp-block"])::-webkit-scrollbar {
	inline-size: 8px;
	block-size: 8px;
}
pre:not([class*="wp-block"])::-webkit-scrollbar-track {
	background: transparent;
}
pre:not([class*="wp-block"])::-webkit-scrollbar-thumb {
	background-color: var(--wp--preset--color--outline-variant);
	border-radius: 9999px;
}
pre:not([class*="wp-block"])::-webkit-scrollbar-thumb:hover {
	background-color: var(--wp--preset--color--outline);
}

/* <kbd> — key cap. Roboto Mono on a slightly higher surface with an inset
 * bottom hairline for the pressed-key affordance. */
kbd {
	font-family: var(--wp--preset--font-family--roboto-mono);
	font-size: var(--wp--preset--font-size--body-medium);
	padding-inline: 0.35em;
	padding-block: 0.15em;
	border-radius: 4px;
	background-color: var(--wp--preset--color--surface-container-high);
	color: var(--wp--preset--color--on-surface);
	box-shadow: inset 0 -1px 0 var(--wp--preset--color--outline-variant);
}
