/* tBeacon redesign — custom.css. Loads after stylesheet.css, wins the cascade. */

/* ==== Fonts: Inter, self-hosted, latin + cyrillic, 400/600/700 ==== */
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('../fonts/inter-cyrillic.woff2') format('woff2');
	unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('../fonts/inter-cyrillic.woff2') format('woff2');
	unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url('../fonts/inter-cyrillic.woff2') format('woff2');
	unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* ==== Palette (accent sampled from the tBeacon logo icon gradient) ==== */
:root {
	--accent: #2495FF;
	--accent-hover: #1C79CC;
	--accent-ink: #291C70;
	--bg: #FFFFFF;
	--bg-subtle: #F6F8FA;
	--border: #E3E7ED;
	--border-strong: #B9C2CE; /* .article-body table only - cards keep --border */
	--text: #1F2430;
	--text-muted: #6B7280;
	--radius: 10px;
	--radius-sm: 8px;
	/* darker than --accent-hover specifically for in-text links on white -
	   plain --accent is ~3:1 (fine for buttons/UI, fails AA for body text);
	   this is ~5.8:1, comfortably clears the 4.5:1 AA threshold */
	--accent-dark: #1567B0;
}

/* ==== Base typography ==== */
body {
	font-family: 'Inter', Arial, sans-serif;
	font-size: 16px;
	color: var(--text);
}
h1, h2, h3, h4, h5, h6,
footer h5 {
	font-family: 'Inter', Arial, sans-serif;
	font-weight: 600;
	color: var(--text);
}
a {
	color: var(--accent);
}
a:hover {
	color: var(--accent-hover);
}

/* ==== Layout air: containers, breadcrumb, cards ==== */
.container {
	padding-left: 24px;
	padding-right: 24px;
}
.breadcrumb {
	background: transparent;
	border: none;
	padding: 12px 0;
	margin: 0 0 28px 0;
}
.breadcrumb > li:after {
	display: none;
}
.breadcrumb > li {
	padding: 0 4px 0 0;
}
.breadcrumb > li + li:before {
	content: '/';
	padding: 0 8px;
	color: var(--text-muted);
}

/* ==== Flat dropdowns (kill the Bootstrap 3 gradient) ==== */
.dropdown-menu li > a:hover,
#top #form-currency .currency-select:hover,
#top #form-language .language-select:hover {
	background-image: none;
	background-color: var(--accent);
}

/* ==== Flat buttons, radius 8-12px, no gradients/shadows ==== */
.btn {
	border-radius: var(--radius);
	box-shadow: none;
}
.btn-primary {
	background-color: var(--accent);
	background-image: none;
	border-color: var(--accent);
}
.btn-primary:hover, .btn-primary:active, .btn-primary.active,
.btn-primary.disabled, .btn-primary[disabled] {
	background-color: var(--accent-hover);
	background-image: none;
	border-color: var(--accent-hover);
	box-shadow: none;
}
.btn-default {
	background-color: #fff;
	background-image: none;
	border-color: var(--border);
	color: var(--text);
}
.btn-default:hover {
	background-color: var(--bg-subtle);
	background-image: none;
}
.btn-inverse {
	background-color: var(--accent-ink);
	background-image: none;
	border-color: var(--accent-ink);
}
.btn-inverse:hover, .btn-inverse:active, .btn-inverse.active {
	background-color: #1E1450;
	background-image: none;
}

/* ==== Semantic buttons: keep meaning, drop the gradient/shadow ==== */
.btn-warning, .btn-danger, .btn-success, .btn-info {
	background-image: none;
	box-shadow: none;
}
.btn-warning:hover, .btn-warning:active, .btn-warning.active,
.btn-danger:hover, .btn-danger:active, .btn-danger.active,
.btn-success:hover, .btn-success:active, .btn-success.active,
.btn-info:hover, .btn-info:active, .btn-info.active {
	box-shadow: none;
}

/* ==== Category nav bar: flat, same accent as buttons/links ==== */
#menu {
	background-color: var(--accent);
	background-image: none;
	border-color: var(--accent-hover);
}
#menu .see-all:hover, #menu .see-all:focus,
#menu .btn-navbar, #menu .btn-navbar:hover, #menu .btn-navbar:focus, #menu .btn-navbar:active {
	background-color: var(--accent-hover);
	background-image: none;
	border-color: var(--accent-hover);
}

/* ==== Forms: same radius as buttons, accent focus ring ==== */
.form-control,
select.form-control, textarea.form-control, input[type="text"].form-control,
input[type="password"].form-control, input[type="email"].form-control {
	border-radius: var(--radius-sm);
	border-color: var(--border);
	box-shadow: none;
}
.form-control:focus {
	border-color: var(--accent);
	box-shadow: 0 0 0 3px rgba(36, 149, 255, 0.15);
	outline: none;
}

/* ==== Alerts: flat toast, incl. add-to-cart success ==== */
.alert {
	border: none;
	border-radius: var(--radius-sm);
	box-shadow: none;
	padding: 12px 18px;
}
.alert-success {
	background-color: #EAF7EE;
	color: #1E7A3D;
}
.alert-danger {
	background-color: #FDECEC;
	color: #B3261E;
}
.alert-info {
	background-color: #EAF3FF;
	color: var(--accent-hover);
}

/* ==== Pagination: flat, accent active/hover ==== */
.pagination > li > a, .pagination > li > span {
	border-color: var(--border);
	color: var(--text);
}
.pagination > li:first-child > a, .pagination > li:first-child > span {
	border-top-left-radius: var(--radius-sm);
	border-bottom-left-radius: var(--radius-sm);
}
.pagination > li:last-child > a, .pagination > li:last-child > span {
	border-top-right-radius: var(--radius-sm);
	border-bottom-right-radius: var(--radius-sm);
}
.pagination > li > a:hover, .pagination > li > a:focus {
	background-color: var(--bg-subtle);
	border-color: var(--accent);
	color: var(--accent-hover);
}
.pagination > .active > a, .pagination > .active > span,
.pagination > .active > a:hover, .pagination > .active > span:hover {
	background-color: var(--accent);
	border-color: var(--accent);
}

/* ==== Product cards: airier padding, flat border, quiet hover ==== */
.product-thumb {
	border-color: var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	transition: transform .15s ease, border-color .15s ease;
}
.product-thumb:hover {
	transform: translateY(-3px);
	border-color: var(--accent);
}
.product-thumb .caption {
	padding: 16px 28px 20px;
}
.product-thumb .button-group {
	background-color: var(--bg-subtle);
	border-top-color: var(--border);
}
.product-thumb .button-group button {
	background-color: transparent;
	color: var(--text-muted);
}
.product-thumb .button-group button:hover {
	background-color: var(--border);
	color: var(--text);
}

/* ==== Sticky header — desktop only ==== */
@media (min-width: 992px) {
	header {
		position: sticky;
		top: 0;
		z-index: 900; /* below #cart .dropdown-menu (1001) and Bootstrap .dropdown-menu (1000) so both open on top, unobstructed */
		background: var(--bg);
		border-bottom: 1px solid var(--border);
	}
}

/* ==== Homepage: comic slideshow — scale to fit, never crop ====
   Reserved box uses the native ratio of comix1-4.png (524x193 = 2.715:1),
   not the module's configured 1140x300 (3.8:1) - the source files don't
   actually match that, and contain+this ratio minimises letterboxing for
   4 of the 6 slides. Wider/portrait outlier slides still fit fully, just
   with more side/top padding inside the box - no crop either way. */
/* Scoped as #content .swiper-viewport (not bare .swiper-viewport): the
   slideshow module injects its own catalog/view/javascript/jquery/swiper/
   css/opencart.css via document->addStyle(), which is rendered through the
   {% for style in styles %} loop AFTER custom.css in header.twig and also
   declares bare .swiper-viewport / .swiper-pagination-bullet-active rules.
   Equal specificity + later in cascade meant opencart.css was winning
   (margin: 0 0 60px; killed centering, its black bullet-active color killed
   the accent dot). #content adds an ID-strength prefix so these rules win
   regardless of style-tag order, including any future addStyle() calls. */
#content .swiper-viewport {
	position: relative;
	max-width: 900px;
	aspect-ratio: 524 / 193;
	margin: 0 auto 32px;
	border-radius: var(--radius);
	border: 1px solid var(--border);
	background: var(--bg-subtle);
	overflow: hidden;
}
#content .swiper-viewport .swiper-container,
#content .swiper-viewport .swiper-wrapper,
#content .swiper-viewport .swiper-slide {
	height: 100%;
}
#content .swiper-viewport .swiper-slide a {
	display: block;
	height: 100%;
}
#content .swiper-viewport .swiper-slide img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}
#content .swiper-viewport .swiper-pagination-bullet-active {
	background: var(--accent);
}
/* The arrow glyph isn't background-image (opencart.css sets that to none) -
   it's a FontAwesome ::before at a fixed 40x40px/font-size:40px, sized for
   the old borderless 27x44 hit area. Our 36px circle is smaller than the
   glyph itself, so centering it needs flex on the button + an explicit
   shrink on ::before, not background-position (which does nothing here). */
#content .swiper-viewport .swiper-button-prev,
#content .swiper-viewport .swiper-button-next {
	width: 36px;
	height: 36px;
	margin-top: -18px;
	background-color: rgba(255, 255, 255, 0.85);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
}
#content .swiper-viewport .swiper-button-prev::before,
#content .swiper-viewport .swiper-button-next::before {
	width: auto;
	height: auto;
	font-size: 16px;
	line-height: 1;
}
/* Mobile: break the slideshow out of .container's side padding so the
   comics render ~14% larger (full device width instead of width minus
   2x24px) - the 3-panel strips are dense enough that every extra pixel
   of on-screen size helps reading them.

   Still too small at that size alone (full-bleed width was already maxed
   at 100vw - no more room there), so this also switches the box to a
   taller-than-native aspect ratio (2.3:1 vs the art's native ~2.72:1) with
   object-fit:cover instead of contain. Since width is already pinned to
   the viewport, the only way to make the art itself render bigger is to
   zoom in and let the excess spill off the left/right edges - cover crops
   ~8% off each side in exchange for ~19% more height (and ~40% more
   visual area). Checked against all 7 slides: no faces/text/product get
   clipped at that crop depth, just a bit of background near the outer
   edges of panels 1 and 3. */
@media (max-width: 768px) {
	#content .swiper-viewport {
		max-width: none;
		width: 100vw;
		aspect-ratio: 2.3 / 1;
		position: relative;
		left: 50%;
		right: 50%;
		margin-left: -50vw;
		margin-right: -50vw;
		border-radius: 0;
		border-left: none;
		border-right: none;
	}
	#content .swiper-viewport .swiper-slide img {
		object-fit: cover;
		object-position: center;
	}
}

/* Slide caption overlay - lives inside the slide's own <a> so the whole
   slide stays one click target; pointer-events:none is belt-and-suspenders. */
#content .swiper-viewport .swiper-slide {
	position: relative;
}
#content .swiper-viewport .slide-caption {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(30, 40, 55, .62);
	color: #fff;
	padding: 10px 14px;
	font-size: 16px;
	line-height: 1.35;
	border-top-left-radius: var(--radius-sm);
	border-top-right-radius: var(--radius-sm);
	pointer-events: none;
	opacity: 0;
	transition: opacity .3s ease .4s;
}
#content .swiper-viewport .swiper-slide-active .slide-caption {
	opacity: 1;
}
@media (max-width: 768px) {
	/* The full-bleed mobile box is short (~144px at 390px wide) - a
	   multi-line caption at the old size ate a third to a half of the
	   art. Single line + ellipsis keeps the bar to one compact strip. */
	#content .swiper-viewport .slide-caption {
		font-size: 11px;
		line-height: 1.3;
		padding: 5px 10px;
		opacity: 1;
		transition: none;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

/* ==== Homepage: featured articles/products blocks ==== */
#content > h3 {
	margin-top: 40px;
	margin-bottom: 20px;
}
#content > h3:first-of-type {
	margin-top: 0;
}
.information-thumb {
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
	transition: transform .15s ease, border-color .15s ease;
}
.information-thumb:hover {
	transform: translateY(-3px);
	border-color: var(--accent);
}
.information-thumb .caption {
	padding: 16px 20px 20px;
}
.information-layout, .product-layout {
	margin-bottom: 24px;
}
/* Equal-height featured-article cards - scoped via :has() to the row
   wrapping .information-layout specifically (bare .row is reused all over
   for unrelated grids). Bootstrap 3's .row is float-based and doesn't
   equalize sibling heights, so a card with a longer (or missing)
   description could differ from its neighbors by 40-60px; the 2-line
   clamp keeps one verbose article from blowing out the whole row even
   with equal-height flex in place. */
#content .row:has(> .information-layout) {
	display: flex;
	flex-wrap: wrap;
}
.information-layout {
	display: flex;
}
.information-thumb {
	display: flex;
	flex-direction: column;
	width: 100%;
}
.information-thumb .caption {
	display: flex;
	flex-direction: column;
	flex: 1;
}
.information-thumb .caption p {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.information-thumb .caption .btn {
	margin-top: auto;
}

/* ==== Content pages (Docs/FAQ/About): long-text typography ====
   Scoped to .article-body, wrapping {{ description }} in information.twig
   (see that commit for why: FAQ's WYSIWYG output is a Bootstrap-accordion
   div-soup, not flat prose - direct-child selectors on #content matched
   nothing). Everything below is a descendant selector under .article-body,
   so it only ever touches the CMS article content, never template chrome
   (.row grids, #specification, #review, related-product/article cards). */
#information-information .article-body {
	max-width: 75ch;
	line-height: 1.6;
	overflow-wrap: break-word;
}
.article-body h2, .article-body h3, .article-body h4 {
	margin-top: 32px;
	margin-bottom: 12px;
	line-height: 1.3;
}
.article-body h2:first-child, .article-body h3:first-child, .article-body h4:first-child {
	margin-top: 0;
}
.article-body p {
	margin: 0 0 16px;
}
.article-body ul, .article-body ol {
	padding-left: 24px;
	margin: 0 0 16px;
}
.article-body li + li {
	margin-top: 6px;
}
.article-body a {
	color: var(--accent-dark);
}

/* Tables */
.article-body table {
	width: 100%;
	border-collapse: collapse;
	margin: 0 0 20px;
	border: 1px solid var(--border-strong);
	border-radius: var(--radius-sm);
	overflow: hidden;
}
.article-body th, .article-body td {
	padding: 10px 14px;
	border: 1px solid var(--border-strong);
	text-align: left;
}
.article-body tr:nth-child(even) {
	background: var(--bg-subtle);
}
@media (max-width: 768px) {
	.article-body table {
		display: block;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
}

/* Images: default = inline icon (no frame, sits in the text line).
   Framed only for the two "standalone image" patterns: a bare img direct
   child of .article-body, or a paragraph whose only content is one img.
   No width threshold - td img and any img with text siblings stay inline. */
.article-body img {
	max-width: 100%;
	height: auto;
	vertical-align: text-bottom;
}
.article-body > img,
.article-body p > img:only-child {
	display: block;
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
}

/* Pre/code */
.article-body code {
	font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
	font-size: 0.9em;
	background: var(--bg-subtle);
	border-radius: var(--radius-sm);
	padding: 2px 6px;
}
.article-body pre {
	font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
	font-size: 0.9em;
	background: var(--bg-subtle);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	padding: 14px 16px;
	margin: 0 0 20px;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}
.article-body pre code {
	background: none;
	padding: 0;
}

/* Blockquote */
.article-body blockquote {
	border-left: 3px solid var(--accent);
	margin: 0 0 20px;
	padding: 4px 0 4px 18px;
	color: var(--text-muted);
}

/* Embedded video */
.article-body iframe {
	max-width: 100%;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	border: none;
	border-radius: var(--radius-sm);
}

/* ==== Stage 6: remaining pages (cart, search, 404, compare, wishlist,
   account forms/tables, contact) - shared Bootstrap components only,
   sitewide (these classes are used identically across all these pages,
   a single flat treatment keeps them consistent). No twig touched except
   checkout/cart.twig scope, explicitly named by owner as an exception to
   the "no checkout templates" rule - see commit for that page. ==== */

/* .well - account/login.twig's two-column boxes */
.well {
	background: var(--bg-subtle);
	border-color: var(--border);
	border-radius: var(--radius);
	box-shadow: none;
}

/* legend/fieldset - register/forgotten/contact forms */
legend {
	font-family: 'Inter', Arial, sans-serif;
	font-weight: 600;
	border-bottom-color: var(--border);
}

/* .panel accordions - cart coupon/shipping, contact location list, FAQ */
.panel {
	border-color: var(--border);
	border-radius: var(--radius-sm);
	box-shadow: none;
}
.panel-default > .panel-heading {
	background-color: var(--bg-subtle);
	border-color: var(--border);
}
.panel-title, .panel-title a {
	color: var(--text);
}

/* .table-bordered - cart, compare, wishlist, order list/info, attribute tables */
.table-bordered {
	border-color: var(--border-strong);
	border-radius: var(--radius-sm);
	overflow: hidden;
}
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th {
	border-color: var(--border);
}
.table-bordered > thead {
	background: var(--bg-subtle);
}
.table-hover > tbody > tr:hover {
	background-color: var(--bg-subtle);
}

/* ==== Card price height fix ====
   Stock OpenCart CSS clamps ".caption > h4 + p" to 70px/overflow:hidden -
   meant for the short-description <p> that normally follows h4. This theme
   comments that description out on cards, so .price (a <p>) becomes the
   literal next sibling of h4 whenever there's no .rating div between them,
   and inherits the clamp by accident. Added specificity via .price wins
   without touching the shared stylesheet.css rule (still correct elsewhere,
   e.g. wherever a real description <p> follows h4). */
.product-thumb .caption > h4 + p.price {
	height: auto;
	overflow: visible;
}

/* ==== Discontinued-product notice (product/product.twig) ====
   Muted amber, not a red alert - the product isn't defective, it's retired. */
.discontinued-notice {
	background: #FDF6E9;
	border: 1px solid #E8D3A0;
	color: #8A6A2E;
	border-radius: var(--radius);
	padding: 16px 20px;
	margin: 0 0 20px;
}
.discontinued-notice a {
	color: #8A6A2E;
	font-weight: 600;
	text-decoration: underline;
}

/* ==== Homepage hero — Content Top, above slideshow.
   Migrated 2026-08-03 from a custom module (extension/module/hero) to a
   stock HTML Content instance (module_id=41, "Hero (главная)") so the
   owner can edit copy from admin. Markup lives in that module's WYSIWYG
   description field now, not a twig template - these classes are the
   contract the WYSIWYG content must keep using. ==== */
.hero-banner {
	text-align: center;
	padding: 56px 0 40px;
}
.hero-heading {
	font-size: 40px;
	line-height: 1.2;
	margin: 0 0 16px;
}
.hero-subheading {
	font-size: 18px;
	color: var(--text-muted);
	max-width: 700px;
	margin: 0 auto 20px;
}
.hero-stats {
	font-size: 15px;
	font-weight: 600;
	color: var(--text);
	margin: 0 0 28px;
}
.hero-button.btn {
	background-color: var(--accent);
	background-image: none;
	border-color: var(--accent);
	color: #fff;
	font-weight: 600;
	font-size: 16px;
	padding: 14px 32px;
	border-radius: var(--radius);
}
.hero-button.btn:hover {
	background-color: var(--accent-hover);
	border-color: var(--accent-hover);
	color: #fff;
}
@media (max-width: 768px) {
	.hero-banner {
		padding: 36px 0 28px;
	}
	.hero-heading {
		font-size: 28px;
	}
	.hero-subheading {
		font-size: 16px;
	}
	.hero-stats {
		font-size: 14px;
	}
}
