/*
Theme Name: Cervotec Identity
Theme URI: https://cervotecsolutions.my/
Description: Child of Twenty Twenty-Five carrying the Cervotec Solutions identity, moved to the simple centred layout: generous whitespace, a pill badge, an oversized headline, one rounded call to action, label-left link-right section headers, big-radius cards, monochrome chrome with colour coming only from content. Self-hosted fonts, no third-party requests.
Author: Cervotec Solutions
Author URI: https://cervotecsolutions.my/
Template: twentytwentyfive
Version: 2.4.3
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cervotec-identity
Tags: business, portfolio, one-column, block-patterns, block-styles, full-site-editing, accessibility-ready
*/

/* ---------------------------------------------------------------------------
   Cervotec identity, v2, 3 October 2026.

   v1 was a sharp system: radius 2px maximum, hairlines everywhere. v2 keeps the
   palette, the typefaces, the hairlines and the ban on shadows, and takes the
   layout and the corners from the simple/centred direction Burhan pointed at.
   The v1 rule this deliberately supersedes is recorded here rather than
   quietly dropped:

     v1 rule 04  "radius 2px maximum"  -> cards and panels 16px, controls 8px,
                                          badges fully rounded. Sharp corners now
                                          read as dated rather than as disciplined.
     unchanged   hairlines not shadows -> still true. Nothing here casts a shadow.
     unchanged   no gradients outside the logo, no third-party font or icon CDN.

   Measured contrast, WCAG 2.1 relative luminance, computed not asserted:
     ink        #111214  on paper #FFFFFF   18.74:1
     ink 2      #4A4C50  on paper            8.60:1
     accent     #FF9D00  as a FILL, ink text 8.99:1
     accent t   #A6440A  as text on paper    6.08:1
     band       #F7F6F3  with ink           17.34:1
   The accent FAILS as body text on white (2.02:1) and FAILS as a button fill
   with a white label (2.08:1). It is a fill for marks and for ink-labelled
   surfaces only. The button uses an ink fill with a paper label, 15.9:1.
   --------------------------------------------------------------------------- */

:root {
	--cv-radius-card: 16px;
	--cv-radius-control: 8px;
	--cv-radius-pill: 999px;
	--cv-hairline: 1px solid var(--wp--preset--color--hairline);
}

/* --- type ------------------------------------------------------------------ */

.cv-label {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--label);
	line-height: 1.6;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-2);
	margin: 0;
}

/* The oversized centred headline. Fluid, so one rule covers the phone and the
   laptop without a media query, and tight, because display type at this size
   needs negative tracking to stop looking loose. */
.cv-display {
	font-size: clamp(2.125rem, 6.2vw, 3.75rem);
	line-height: 1.08;
	letter-spacing: -0.022em;
	font-weight: 600;
	text-wrap: balance;
	max-width: 16ch;
	margin-left: auto;
	margin-right: auto;
}

.cv-lede {
	font-size: clamp(1rem, 2.2vw, 1.125rem);
	line-height: 1.5;
	max-width: 40ch;
	margin-left: auto;
	margin-right: auto;
	text-wrap: balance;
}

.cv-mono,
.cv-figure {
	font-family: var(--wp--preset--font-family--mono);
	font-variant-numeric: tabular-nums;
}

.cv-numbers {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--secondary);
	line-height: 1.6;
	color: var(--wp--preset--color--ink-2);
	margin: 0;
}

/* --- the small round badge above the headline ------------------------------ */

p.cv-badge {
	display: block;
	width: fit-content;
	margin: 0 auto 24px;
	border: var(--cv-hairline);
	border-radius: var(--cv-radius-pill);
	padding: 6px 14px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--label);
	line-height: 1.6;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-2);
	background: var(--wp--preset--color--paper);
}

/* --- structure ------------------------------------------------------------- */

.cv-hairline {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	margin: 0;
	opacity: 1;
}

/* Section dividers span the full width of the page. Nothing is needed to make
   that happen: the landing template is unconstrained while each section group
   imposes its own 720px measure, so a separator sitting between them is already
   as wide as the viewport. An earlier attempt used `width: 100vw` plus negative
   margins, which overflowed by 8px on a desktop with a scrollbar (100vw includes
   the scrollbar) and then, after the template was unconstrained, double-bled by
   48px. Measured on the live page: 0px of horizontal overflow is the acceptance
   test, and this file must not reintroduce a viewport unit. */
.cv-hairline.alignfull {
	max-width: none;
}

/* The sticky header lives on the template-part WRAPPER, not on the group inside
   it. A sticky element can only travel inside its containing block, and the
   wrapper is exactly as tall as the header, so stickiness declared on the inner
   group could never move: it measured as position:sticky and still scrolled away. */
.cv-header {
	position: sticky;
	top: 0;
	z-index: 20;
}

/* --- brand ----------------------------------------------------------------
   Supplied as four files on 3 October 2026 and kept byte-identical in
   assets/brand/. The site has no dark surface, so the dark-on-light variant is
   the one in use; logo-light.svg (white) is kept for a future dark band or
   footer. Wordmark colours are pure black and pure white as delivered, not the
   ink token, so the artwork stays reproducible from the source files. */
.cv-logo,
.cv-logo-footer {
	margin: 0;
	line-height: 0;
}

.cv-logo img,
.cv-logo-footer img {
	display: block;
	height: 40px;
	width: auto;
}

.cv-logo-footer img {
	height: 32px;
}

/* The logo is a link home; do not underline it or tint it on hover. */
.cv-logo a {
	text-decoration: none;
}

.cv-band {
	background: var(--wp--preset--color--band);
	border-top: 1px solid var(--wp--preset--color--hairline);
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}

/* label left, link right. This is the whole header of a section. */
.cv-section-head {
	border: 0;
	padding: 0;
	margin: 0 0 20px;
	gap: 16px;
}

.cv-section-head p {
	margin: 0;
}

.cv-section-head a {
	text-decoration: none;
	color: var(--wp--preset--color--ink-2);
}

.cv-section-head a:hover {
	color: var(--wp--preset--color--accent-text);
}

/* --- surfaces -------------------------------------------------------------- */

.cv-card {
	border: var(--cv-hairline);
	border-radius: var(--cv-radius-card);
	padding: 24px;
	background: var(--wp--preset--color--paper);
}

.cv-panel {
	border: var(--cv-hairline);
	border-radius: var(--cv-radius-card);
	padding: 32px 24px;
	background: var(--wp--preset--color--paper);
}

.cv-panel > *:first-child {
	margin-top: 0;
}

.cv-panel > *:last-child {
	margin-bottom: 0;
}

/* The measurement band: real service output, monospaced, no decoration. */
.cv-terminal {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--band);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--secondary);
	line-height: 1.6;
	padding: 20px;
	border-radius: var(--cv-radius-card);
	overflow-x: auto;
}

.cv-terminal .cv-ok { color: #7BD88F; }
.cv-terminal .cv-dim { color: #8A8D93; }

/* --- the alternate landing page -------------------------------------------
   The structure of a trending dark SaaS template (a Cauras landing page,
   aura.build) rebuilt in this identity: same bones, white paper instead of
   near-black, hairlines instead of glows, no gradients, no shadows. The
   template's logo strip, testimonial wall and template gallery are absent
   because we have no logos, no testimonials and no gallery to show, and
   inventing them is the one thing the brief forbids. */

/* Both page-width devices, and the trap they share.
   WordPress's constrained layout caps EVERY direct child at
   --wp--style--global--content-size and centres it with `margin: auto !important`.
   So a left-aligned hero floats in the middle, and a plain `margin-left: 0`
   loses to the !important. Two rules settle it:

     1. the content size is raised to the container width, which makes the cap a
        no-op and the auto margins resolve to zero;
     2. every direct child is pinned left.

   `.cv-wide` is a 1080 column centred in the page. `.cv-band` is full-bleed, so
   it carries its own gutter of `(100% - 1080px) / 2` to put its content on the
   same 1080 axis as everything else. Without that gutter a full-bleed band with
   left-pinned children would jam them against the viewport edge. */
.cv-wide.is-layout-constrained,
.cv-band.is-layout-constrained {
	--wp--style--global--content-size: var(--wp--style--global--wide-size);
}

.cv-wide.is-layout-constrained > *,
.cv-band.is-layout-constrained > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

.cv-wide {
	max-width: var(--wp--style--global--wide-size);
	margin-left: auto !important;
	margin-right: auto !important;
}

/* A `.cv-wide` group that is a direct child of the page content is already a
   1080 column centred on the page, so WordPress's global root padding insets
   its children a second time and drops them 24px off the axis every `.cv-band`
   section sits on. Above the axis width there is no gutter left to provide;
   below it the root padding has to stay or text would touch the viewport edge.
   1128px is the axis plus both gutters. */
@media (min-width: 1128px) {
	.wp-block-post-content > .cv-wide.is-layout-constrained.has-global-padding {
		padding-left: 0;
		padding-right: 0;
	}
}

.cv-band {
	padding-left: max(24px, calc((100% - var(--wp--style--global--wide-size)) / 2)) !important;
	padding-right: max(24px, calc((100% - var(--wp--style--global--wide-size)) / 2)) !important;
}

/* Full-bleed bands stack flush, separated only by their own hairlines. The
   theme's block gap otherwise leaves a 24px strip of page background above and
   below every band, which reads as a rendering fault rather than as spacing,
   and it lands between the coloured bands where nothing should be visible.
   WordPress applies the gap with `:where()`, so a plain class selector wins
   here without needing `!important`. */
.wp-block-post-content > * + .cv-band,
.wp-block-post-content > .cv-band + * {
	margin-block-start: 0;
}

/* WordPress wraps each template part in its own element and puts the site-level
   block gap on that wrapper, not on the part inside it. Header, page content and
   footer are all full-bleed, so the gap lands as a 24px strip of page background
   between the last band and the footer. The header is unaffected because the
   main group in the page template already pins its own margins to zero. */
.wp-site-blocks .wp-block-template-part {
	margin-block-start: 0;
	margin-block-end: 0;
}

.cv-display--left {
	text-align: left;
	max-width: 20ch;
}

.cv-lede--left {
	text-align: left;
	max-width: 52ch;
}

.cv-h2-lead {
	font-size: clamp(1.5rem, 3.2vw, 2.125rem);
	line-height: 1.15;
	letter-spacing: -0.018em;
	max-width: 26ch;
	margin: 0 0 32px;
}

/* A framed panel, the equivalent of the template's browser-chrome mockup. It
   holds our own build output, which is the only product screenshot we can show
   honestly. A mono title bar instead of fake window dots: the dots would be
   decoration, and decoration is not what this identity does. */
.cv-frame {
	border: var(--cv-hairline);
	border-radius: var(--cv-radius-card);
	overflow: hidden;
	background: var(--wp--preset--color--ink);
}

.cv-frame__bar {
	margin: 0;
	padding: 12px 20px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--label);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: #8A8D93;
	border-bottom: 1px solid #2A2C30;
	background: var(--wp--preset--color--ink);
}

.cv-frame .cv-terminal {
	border-radius: 0;
	background: var(--wp--preset--color--ink);
}

/* `white-space: pre` belongs on the LINE, not on the container. On the container
   it also preserves the newlines and indentation that the block editor emits
   BETWEEN blocks, so a seven-line log renders as a mostly-empty black panel. */
.cv-terminal p {
	margin: 0;
	white-space: pre;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--secondary);
}

/* The bento grid: the template's icon-cell board, kept as bordered cells. */
.cv-bento {
	margin-bottom: 12px;
}

.cv-cell {
	border: var(--cv-hairline);
	border-radius: var(--cv-radius-card);
	padding: 20px;
	background: var(--wp--preset--color--paper);
}

.cv-cell h3 {
	margin-top: 0;
	margin-bottom: 8px;
	font-size: var(--wp--preset--font-size--medium);
}

.cv-cell p {
	margin-bottom: 0;
}

/* One card in the row carries the weight, the way the template highlights its
   middle pricing tier. No price is shown, here or anywhere. */
.cv-card--accent {
	border-color: var(--wp--preset--color--accent);
	box-shadow: inset 3px 0 0 0 var(--wp--preset--color--accent);
}

/* Numbered process steps, separated by hairlines rather than boxed. */
.cv-step {
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--hairline);
	border-radius: 0;
}

.cv-step:last-child {
	border-bottom: 0;
}

.cv-step p {
	margin: 0;
}

.cv-step p.cv-label {
	margin-bottom: 6px;
	color: var(--wp--preset--color--accent-text);
}

/* FAQ. <details> gets a hairline top and a summary marker that matches the type. */
.cv-faq {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	border-radius: 0;
	padding: 20px 0;
	margin: 0;
}

.cv-faq:last-of-type {
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}

.cv-faq summary {
	cursor: pointer;
	font-weight: 500;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.3;
	list-style: none;
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 16px;
}

.cv-faq summary::-webkit-details-marker {
	display: none;
}

.cv-faq summary::after {
	content: "+";
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--large);
	color: var(--wp--preset--color--ink-2);
	line-height: 1;
}

.cv-faq[open] summary::after {
	content: "\2212";
}

.cv-faq p {
	margin: 12px 0 0;
	max-width: 62ch;
	color: var(--wp--preset--color--ink-2);
}

/* --- the Northline translation --------------------------------------------
   Structure of a dark creative-studio template (northline-creative-02 on
   aura.build) in this identity. That template is orange on near-black, and so
   are we, so the band rhythm survives almost intact: its #111213 becomes our
   ink, its #ff6a1a becomes our accent, its #e9e7e1 becomes our band.

   What does NOT survive: the full-bleed photograph its hero is built on, and
   the four-figure statistics band beneath it. We have no photography, and
   inventing numbers is the one thing the brief forbids, so the hero is type on
   ink and the statistics band became our four working principles. Everything
   below is measured, not asserted:

     paper  #FFFFFF on ink     #111214   18.74:1
     accent #FF9D00 on ink               9.09:1
     ink    on accent                    9.09:1

   Note the last two: the accent is legible AS TEXT ON INK here, which is why
   the hero can use it for links. On paper it cannot, and does not. */

.cv-ink {
	background-color: var(--wp--preset--color--ink) !important;
	color: #D6D8DB;
}

.cv-ink h1,
.cv-ink h2,
.cv-ink h3 {
	color: var(--wp--preset--color--paper) !important;
}

.cv-ink p {
	color: #D6D8DB;
}

.cv-ink .cv-label,
.cv-ink .cv-numbers {
	color: #8A8D93 !important;
}

.cv-ink a:not(.wp-block-button__link) {
	color: var(--wp--preset--color--accent);
}

/* On ink, the default button would be an ink fill with a paper label, which is
   invisible against its own band: this is what happened when the first version
   of the hero shipped, and the primary call to action read as orange text with
   no button around it. Inverted instead: paper fill, ink label, 18.74:1. */
.cv-ink .wp-block-button:not(.is-style-outline) .wp-block-button__link {
	background: var(--wp--preset--color--paper) !important;
	color: var(--wp--preset--color--ink) !important;
}

.cv-ink .cv-hairline,
.cv-ink .cv-hairline--ink {
	border-top-color: rgba(255, 255, 255, 0.22) !important;
}

.cv-ink .wp-block-button.is-style-outline .wp-block-button__link {
	background: transparent !important;
	color: var(--wp--preset--color--paper) !important;
	border: 1px solid rgba(255, 255, 255, 0.32);
}

.cv-accent {
	background-color: var(--wp--preset--color--accent) !important;
	color: var(--wp--preset--color--ink);
}

.cv-accent h1,
.cv-accent h2,
.cv-accent h3,
.cv-accent p,
.cv-accent .cv-label,
.cv-accent .cv-numbers,
.cv-accent a {
	color: var(--wp--preset--color--ink) !important;
}

.cv-accent .wp-block-button__link {
	background: var(--wp--preset--color--ink) !important;
	color: var(--wp--preset--color--paper) !important;
}

/* The display size the template uses: near-solid leading, tight tracking,
   medium weight rather than bold. */
.cv-hero-xl {
	font-size: clamp(2.25rem, 7.4vw, 5.25rem);
	line-height: 0.96;
	letter-spacing: -0.03em;
	font-weight: 500;
	max-width: 18ch;
	margin: 24px 0 0;
}

.cv-meta-row {
	border: 0;
	padding: 0;
	margin-top: 40px;
	gap: 16px;
}

.cv-meta-row p {
	margin: 0;
}

/* The four-up band under the hero. A rule above each cell, label over value,
   the shape the template uses for its statistics. */
.cv-fact {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--ink);
	border-radius: 0;
	padding-top: 16px;
}

.cv-fact p {
	margin: 0;
}

.cv-fact p.cv-label {
	margin-bottom: 10px;
}

/* Capability rows: separated by hairlines, not boxed. */
.cv-cap {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	border-radius: 0;
}

.cv-cap:first-child {
	border-top: 0;
	padding-top: 0 !important;
}

.cv-cap h3 {
	margin: 0 0 8px;
}

.cv-cap p {
	margin: 0;
	max-width: 62ch;
}

/* Process stages, with an ink rule rather than a hairline so they read as a
   deliberate sequence on the band background. */
.cv-stage {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--ink);
	border-radius: 0;
	padding-top: 16px !important;
}

.cv-stage h3 {
	margin: 8px 0;
}

.cv-stage p {
	margin: 0;
}

/* Two-up questions, hairline above each. */
.cv-qa {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	border-radius: 0;
	padding-top: 20px !important;
}

.cv-qa h3 {
	margin: 0 0 8px;
	font-size: var(--wp--preset--font-size--medium);
}

.cv-qa p {
	margin: 0;
}

/* Two engagement shapes, the template's "ways to work together" slot. Card one
   is a bordered panel on ink; card two is the accent-filled card, which is the
   same device the template uses to mark its recommended option. Our accent with
   ink text is 9.09:1, and there is no price on either card, because the page
   carries no prices. */
.cv-label--accent {
	color: var(--wp--preset--color--accent) !important;
}

.cv-ink .cv-label--accent {
	color: var(--wp--preset--color--accent) !important;
}

.cv-offer {
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: var(--cv-radius-card);
	padding: 24px;
	background: transparent;
}

.cv-offer h3 {
	margin: 20px 0 0;
	font-size: 1.5rem;
	letter-spacing: -0.02em;
}

.cv-offer p {
	margin: 12px 0 0;
	color: #A9ACB1;
}

.cv-offer p.cv-label {
	margin: 0;
}

.cv-offer .cv-offer__meta {
	margin-top: 32px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--secondary);
}

.cv-offer--accent {
	background: var(--wp--preset--color--accent) !important;
	border-color: var(--wp--preset--color--accent);
}

.cv-offer--accent h3,
.cv-offer--accent p,
.cv-offer--accent .cv-label {
	color: var(--wp--preset--color--ink) !important;
}

/* --- enforcement ----------------------------------------------------------- */

/* No shadows anywhere. The direction is flat, so we are flat. */
.wp-block-button__link,
.wp-element-button,
.wp-block-image img,
.wp-block-group,
.wp-block-columns,
.wp-block-column {
	box-shadow: none !important;
}

.wp-block-image img,
input,
textarea,
select {
	border-radius: var(--cv-radius-control) !important;
}

/* Radius is set here and not only in theme.json, so the rule is greppable in
   one place and a block style cannot quietly reintroduce a sharp corner. */
.wp-block-button__link,
.wp-element-button {
	border-radius: var(--cv-radius-control) !important;
	padding: 14px 24px;
	font-weight: 500;
	transition: background-color 120ms ease, color 120ms ease;
}

/* Links in body copy are underlined; nav, buttons and section links are not. */
.wp-block-navigation a,
.wp-block-button a {
	text-decoration: none;
}

/* The nav is small, spaced caps. It is a signpost, not a feature. */
.wp-block-navigation .wp-block-navigation-item__content {
	font-size: var(--wp--preset--font-size--label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-2);
	padding-left: 12px;
	padding-right: 12px;
}

.wp-block-navigation .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--ink);
}

@media (max-width: 599px) {
	.cv-card,
	.cv-panel {
		padding: 20px;
	}
}

/* Skip link, always available. */
.cv-skip:not(:focus) {
	position: absolute;
	left: -9999px;
}

@media (prefers-reduced-motion: reduce) {
	* { animation: none !important; transition: none !important; }
}
