.ecom-libro {
font-family: Arial, sans-serif;
font-size: 14px;
color: #333;
}
.ecom-libro .main-container,
.ecom-libro .container {
width: 100%;
margin: 40px auto;
display: flex;
gap: 24px;
}
.ecom-libro .main-container {
max-width: 1200px;
}
.ecom-libro .container {
padding: 1em 5em;
}
.ecom-libro .top-section {
display: flex;
align-items: flex-start;
gap: 24px;
}
.ecom-libro .promo-banner {
display: flex;
align-items: center;
justify-content: center;
background: #111;
color: #fff;
font-size: 14px;
padding: 12px 20px;
gap: 8px;
}
.ecom-libro .promo-banner .discount {
color: #ffd700;
font-weight: bold;
}
.ecom-libro .promo-banner .conditions {
display: flex;
align-items: center;
font-weight: bold;
text-decoration: none;
color: #fff;
}
.ecom-libro .promo-banner .conditions:hover {
text-decoration: underline;
}
.ecom-libro .promo-banner .conditions i {
margin-left: 4px;
font-size: 16px;
}
.ecom-libro .product-detail {
flex: 1;
background: #fff;
padding: 24px;
border-radius: 4px;
}
.ecom-libro .header-book {
display: flex;
align-items: flex-start;
gap: 16px;
margin-bottom: 16px;
}
.ecom-libro .header-book .logo-book {
height: auto;
width: auto;
max-height: 400px;
max-width: 300px;
}
.ecom-libro .title {
font-family: 'SohoPro-Regular';
font-size: 24px;
color: #00437a;
margin-top: 0;
font-weight: bold;
}
.ecom-libro .description-book {
margin: 20px 0 10px;
font-size: 1.2em;
font-weight: 600;
line-height: 1.4;
color: #222;
}
.ecom-libro .btn {
display: inline-block;
font-family: 'SohoPro-Regular';
font-weight: bold;
padding: 8px 16px;
text-decoration: none;
}
.ecom-libro .extract-btn {
font-size: 1em !important;
border: 2px solid #00437a;
color: #00437a;
transition: background .2s, color .2s;
text-transform: none !important;
}
.ecom-libro .extract-btn:hover {
background: #e6f0ff;
color: #120e5b;
}
.ecom-libro .purchase-box {
flex: 0 0 300px;
background: #f3f6f9;
padding: 10px 0 15px;
border-radius: 4px;
text-align: center;
}
.ecom-libro .purchase-box .price-header {
padding: 16px;
text-align: left;
}
.ecom-libro .purchase-box .price-header .price {
font-family: 'SohoPro-Regular';
font-size: 28px;
font-weight: bold;
color: #0046ad;
margin-bottom: 0;
}
.ecom-libro .purchase-box .price-header .old-price {
font-family: 'SohoPro-Regular';
font-size: bold;
color: #25323c;
font-size: 20px;
text-decoration: line-through;
margin-bottom: 0;
}
.ecom-libro .purchase-box .price-header .discount {
font-family: 'SohoPro-Regular';
display: inline-block;
background-color: var(--ae-450, #D44436);
color: #fff;
font-size: 1rem;
font-weight: bold;
padding: 0.3em 0.3em;
margin-left: 0.4em;
border-radius: 0.2em;
line-height: 1;
text-align: center;
}
.ecom-libro .purchase-box .price-header .note {
font-family: sans-serif;
font-size: 12px;
font-weight: 500;
color: #000;
margin-bottom: 0;
}
.ecom-libro .purchase-box .selectors {
display: flex;
align-items: center;
gap: 8px;
padding: 0 16px 16px;
}
.ecom-libro .purchase-box .selectors .qty {
flex: 0 0 50px;
}
.ecom-libro .purchase-box .selectors input,
.ecom-libro .purchase-box .selectors select {
width: 100%;
height: 40px;
padding: 0 12px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: #fff;
}
.ecom-libro .purchase-box .selectors select {
background-image: url(/documents/d/global/ico-chevron-down);
background-repeat: no-repeat;
background-size: 18px 10px;
background-position: right 12px center;
}
.ecom-libro .purchase-box .selectors select::-ms-expand {
display: none;
}
.ecom-libro .purchase-box .selectors .selector {
position: relative;
flex: 1;
}
.ecom-libro .purchase-box .selectors .selector .arrow {
position: absolute;
top: 50%;
right: 12px;
transform: translateY(-50%);
pointer-events: none;
font-size: 12px;
color: #666;
}
.ecom-libro .purchase-box .selectors .selector:focus-within {
background-size: 18px 10px;
background-position-x: 95%;
}
.ecom-libro .purchase-box .buy-btn {
width: calc(100% - 32px);
text-transform: uppercase;
}
.ecom-libro .purchase-box .buy-btn:hover,
.ecom-libro .purchase-box .buy-btn:focus,
.ecom-libro .purchase-box .buy-btn:focus-visible {
outline: 2px solid var(--brand-color-2, #6a9bd3);
outline-offset: 2px;
box-shadow: 0 0 0 3px rgba(106, 155, 211, 0.35);
}
.ecom-libro .purchase-box .buy-btn.disabled,
.ecom-libro .purchase-box .buy-btn:disabled,
.ecom-libro .purchase-box .buy-btn[disabled],
.ecom-libro .purchase-box .buy-btn.ecom-btn-loading {
opacity: .6;
pointer-events: none;
}
.ecom-libro .purchase-box .buy-btn.ecom-btn-loading::before,
.ecom-libro .purchase-box .buy-btn.ecom-btn-loading::after {
display: none;
}
.ecom-libro .tabs-section {
max-width: 900px;
margin: 0 auto 40px;
padding-top: 3em;
background: #fff;
border-radius: 4px;
overflow: hidden;
}
.ecom-libro .tabs-section .tabs {
display: flex;
border-bottom: 1px solid #ddd;
}
.ecom-libro .tabs-section .tab {
padding: 12px 16px;
margin-right: 8px;
background: transparent;
border: none;
border-radius: 4px 4px 0 0;
cursor: pointer;
font-size: 14px;
color: #222;
transition: background .2s;
}
.ecom-libro .tabs-section .tab:hover {
background: rgba(0, 67, 122, 0.05);
}
.ecom-libro .tabs-section .tab.active {
color: #00437a;
background: #e5f5ff;
border-bottom: 2px solid #00437a;
font-weight: bold;
}
.ecom-libro .tabs-section table {
width: 100%;
border-collapse: collapse;
}
.ecom-libro .tabs-section th,
.ecom-libro .tabs-section td {
padding: 12px 16px;
vertical-align: middle;
}
.ecom-libro .tabs-section th {
width: 180px;
font-weight: 600;
color: #444;
text-align: right;
white-space: nowrap;
}
.ecom-libro .tabs-section td {
font-weight: 400;
color: #222;
line-height: 1.4;
}
.ecom-libro .tabs-section tr:nth-child(even) > * {
background: #f9fafb;
}
.ecom-libro .tabs-section .badge {
display: inline-block;
margin-left: 8px;
padding: 2px 6px;
font-size: 11px;
text-transform: uppercase;
border-radius: 3px;
}
.ecom-libro .tabs-section .tag-success {
background: #2a7a36;
color: #fff;
}
.ecom-libro .tabs-section .tag-danger {
background: #c00000;
color: #fff;
}
/* === Media queries === */
@media (max-width: 1024px) {
.ecom-libro .main-container { padding: 20px; margin: 20px auto; }
.ecom-libro .top-section { flex-direction: column; gap: 16px; }
.ecom-libro .purchase-box { flex: none; width: 100%; }
.ecom-libro .product-detail { padding: 16px; }
.ecom-libro .title { font-size: 18px; }
}
@media (max-width: 768px) {
.ecom-libro { font-size: 13px; }
.ecom-libro .promo-banner { flex-direction: column; text-align: center; gap: 4px; padding: 8px 10px; }
.ecom-libro .main-container { margin: 16px auto; }
.ecom-libro .top-section { gap: 12px; }
.ecom-libro .title { font-size: 16px; }
.ecom-libro .extract-btn { padding: 6px 12px; font-size: 13px; }
.ecom-libro .selectors { flex-direction: column; gap: 8px; padding: 12px; }
.ecom-libro .buy-btn { width: 100%; margin-bottom: 16px; }
.ecom-libro .tabs-section .tabs { flex-wrap: wrap; justify-content: center; }
}
.ecom-libro .autores-list {
display: flex;
flex-wrap: wrap;
gap: 8px 12px;
margin-top: 15px;
}
.ecom-libro .autor-item {
display: flex;
align-items: center;
gap: 6px;
background-color: #E6F7FF;
border-radius: 4px;
padding: 4px 8px;
}
.ecom-libro .autor-nombre {
font-size: 1rem;
font-weight: bold;
color: #273469;
}
.ecom-libro .autor-add {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
font-size: 2em;
color: #4AC8F0;
background: none;
border: none;
cursor: pointer;
border-radius: 4px;
}
.ecom-libro .info-box-book {
display: inline-flex;
width: 100%;
align-items: center;
background-color: #ffffd7;
margin-top: 10px;
padding: 4px 8px;
border-radius: 4px;
color: #273469;
}
.ecom-libro .info-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5em;
height: 1.5em;
margin-right: 8px;
border: 2px solid #273469;
border-radius: 50%;
font-size: 1em;
font-weight: bold;
}
.ecom-libro .book-description {
margin-top: 2em;
}
/* ===== estilos de la modal ===== */
.ecom-libro .modal {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
display: none;
z-index: 1000;
align-items: center;
justify-content: center;
}
.ecom-libro .modal.show { display: flex; }
.ecom-libro .modal-content {
background: #fff;
border-radius: 8px;
width: 100%;
max-height: 70vh;
overflow-y: auto;
max-width: 600px;
position: relative;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
font-family: 'SohoPro-Regular';
}
.ecom-libro .modal-header {
font-size: 1.25rem;
font-weight: bold;
border: none;
}
.ecom-libro .modal-close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: none;
border: none;
font-size: 1.25rem;
cursor: pointer;
color: #999;
}
.ecom-libro .modal-close:hover {
color: #333;
}
window.ecomGenericScripts = window.ecomGenericScripts || (function () {
/* =====================================
PROPIEDADES PRIVADAS
===================================== */
const privateProps = window.ecomGenericScripts?.privateProps || {};
/* =====================================
PROPIEDADES PÚBLICAS
===================================== */
const publicProps = {
isDebug: false
};
/* =====================================
FUNCIONES PÚBLICAS
===================================== */
//En functions declaramos la functions publicas
const functions = {};
functions.init = async function () {
await _DOMContentLoaded();
};
/* =====================================
FUNCIONES PRIVADAS
===================================== */
const _loadInit = async function () {
if (publicProps.isDebug) console.log("DOMContentLoaded ecom Generic scripts");
};
const _parsePriceText = function (text) {
if (!text) return 0;
const cleaned = String(text)
.replace(/[^\d,.-]/g, "")
.replace(/\./g, "")
.replace(",", ".");
const n = Number(cleaned);
return Number.isFinite(n) ? n : 0;
};
const _getDetailContext = function (button) {
const wrapper = document.querySelector("#ecom-scripts .data-product-wrapper");
const purchaseBox = button?.closest(".purchase-box") || document;
const langSelect = purchaseBox.querySelector(".select-language");
const formatSelect = purchaseBox.querySelector(".select-format");
const qtyInput = purchaseBox.querySelector(".qty input[type='number']");
const priceNode = purchaseBox.querySelector(".price-header .price");
const titleNode = document.querySelector(".ecom-libro .title, .ecom-norma .title, .ecom-coleccion_tematica .title, .title-book");
return {
wrapper,
purchaseBox,
langSelect,
formatSelect,
qtyInput,
priceNode,
titleNode
};
};
const _getDetailData = async function (productERC, productId, isLibro, isNorma, isColeccionTematica) {
if (!window.ecomGlobalScripts?.functions) return null;
try {
if (isLibro) {
if (productERC) return await window.ecomGlobalScripts.functions.getProductBooksByERC(productERC);
if (productId) return await window.ecomGlobalScripts.functions.getProductBooks(productId);
}
if (isColeccionTematica) {
if (productERC) return await window.ecomGlobalScripts.functions.getProductThematicCollectionsByERC(productERC);
if (productId) return await window.ecomGlobalScripts.functions.getProductThematicCollections(productId);
}
if (isNorma) {
if (productERC) return await window.ecomGlobalScripts.functions.getProductNormasDetailsByERC(productERC);
if (productId) return await window.ecomGlobalScripts.functions.getProductNormasDetails(productId);
}
} catch (e) {}
return null;
};
const _syncDetailBuyButtonState = function (purchaseBox) {
if (!purchaseBox) return;
const btn = purchaseBox.querySelector(".buy-btn");
if (!btn) return;
const langSelect = purchaseBox.querySelector(".select-language");
const formatSelect = purchaseBox.querySelector(".select-format");
const hasSelectors = !!(langSelect || formatSelect);
const hasSelection = !!(langSelect?.value && formatSelect?.value);
if (!hasSelectors) {
if (!btn.disabled) btn.disabled = true;
if (!btn.classList.contains("disabled")) btn.classList.add("disabled");
return;
}
if (btn.disabled === hasSelection) {
btn.disabled = !hasSelection;
}
btn.classList.toggle("disabled", !hasSelection);
};
const _setupQtyPriceMultiplier = function (purchaseBox) {
if (!purchaseBox || purchaseBox.dataset.aeQtyMultBound === "true") return;
purchaseBox.dataset.aeQtyMultBound = "true";
const priceNode = purchaseBox.querySelector(".price-header .price");
const qtyInput = purchaseBox.querySelector(".qty input[type='number']");
if (!priceNode || !qtyInput) return;
const formatter = window.ecomGlobalScripts?.properties?.language?.formatterPrice;
const splitPriceAndCurrency = function (text) {
const m = String(text || "").match(/^(.*?)(\s*[^\d.,\s]+)\s*$/);
if (m) return [m[1].trim(), m[2].trim()];
return [String(text || "").trim(), ""];
};
const formatPrice = function (value, currency) {
const numText = formatter
? formatter.format(value)
: value.toLocaleString("es-ES", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
return currency ? numText + " " + currency : numText;
};
const captureUnit = function () {
const parts = splitPriceAndCurrency(priceNode.textContent);
const parsed = _parsePriceText(parts[0]);
if (parsed > 0) {
purchaseBox.dataset.aeUnitPrice = String(parsed);
purchaseBox.dataset.aeUnitCurrency = parts[1];
}
};
let observer;
const startObserve = function () {
observer.observe(priceNode, { childList: true, characterData: true, subtree: true });
};
const reapply = function () {
const unit = Number(purchaseBox.dataset.aeUnitPrice) || 0;
if (!unit) return;
const qty = Math.max(1, parseInt(qtyInput.value, 10) || 1);
const total = unit * qty;
const currency = purchaseBox.dataset.aeUnitCurrency || "";
if (observer) observer.disconnect();
priceNode.textContent = formatPrice(total, currency);
if (observer) startObserve();
};
// Cuando _renderFragmentPrice (en ECOM-Global_functions/index.js) reescribe
// .price con el precio unitario tras cambiar idioma/formato, recapturamos
// el unitario y reaplicamos la cantidad actual.
observer = new MutationObserver(function () {
captureUnit();
reapply();
});
startObserve();
qtyInput.addEventListener("input", reapply);
qtyInput.addEventListener("change", reapply);
// Captura inicial por si el precio ya estaba renderizado antes de montar el observer.
captureUnit();
reapply();
};
const _bindDetailSelectorState = function (purchaseBox) {
if (!purchaseBox) return;
const sync = function () {
_syncDetailBuyButtonState(purchaseBox);
};
if (purchaseBox.dataset.aeSelectorsBound === "true") {
sync();
return;
}
purchaseBox.dataset.aeSelectorsBound = "true";
purchaseBox.addEventListener("change", function (event) {
if (!event.target?.matches(".select-language, .select-format")) return;
sync();
});
const selectorsRoot = purchaseBox.querySelector(".selector-language_format") || purchaseBox;
const observer = new MutationObserver(function () {
sync();
});
observer.observe(selectorsRoot, {
childList: true,
subtree: true
});
sync();
};
const _attachDetailAddToCart = async function () {
const buttons = document.querySelectorAll(".purchase-box .buy-btn");
if (!buttons.length) return;
buttons.forEach(btn => {
_bindDetailSelectorState(btn.closest(".purchase-box"));
_setupQtyPriceMultiplier(btn.closest(".purchase-box"));
if (btn.dataset.aeBound === "true") return;
btn.dataset.aeBound = "true";
btn.addEventListener("click", (e) => {
e.preventDefault();
const run = async () => {
const ctx = _getDetailContext(btn);
const wrapper = ctx.wrapper;
if (!wrapper) {
window.dispatchEvent(new CustomEvent("cart:error", { detail: { message: "Error al añadir el producto a la cesta" } }));
return;
}
const productId = Number(wrapper.dataset.productId) || null;
const productERC = wrapper.dataset.productErc || "";
const isLibro = wrapper.dataset.productIslibro === "true";
const isNorma = wrapper.dataset.productIsnorma === "true";
const isColeccionTematica = wrapper.dataset.productIscolecciontematica === "true";
const codIdioma = (ctx.langSelect?.value || "").toString();
const codFormato = (ctx.formatSelect?.value || "").toString();
if ((ctx.langSelect || ctx.formatSelect) && (!codIdioma || !codFormato)) {
window.dispatchEvent(new CustomEvent("cart:error", { detail: { message: "Selecciona idioma y formato" } }));
return;
}
const entryType = isLibro ? "Libro" : isColeccionTematica ? "Colección Temática" : "Norma";
const code = productERC || (ctx.titleNode?.textContent || "").trim();
const qty = Math.max(1, parseInt(ctx.qtyInput?.value, 10) || 1);
const name = (ctx.titleNode?.textContent || "").trim();
let priceToSend = 0;
const data = await _getDetailData(productERC, productId, isLibro, isNorma, isColeccionTematica);
if (Array.isArray(data) && data.length && codIdioma && codFormato) {
const entry = data.find(item => {
const langKey = item.codLanguage ?? item.language;
const fmtKey = item.codFormat ?? item.format;
return String(langKey) === codIdioma && String(fmtKey) === codFormato;
});
if (entry) {
const basePrice = Number(entry.price) || 0;
const discount = Number(entry.webDiscount) || 0;
priceToSend = discount > 0 ? Math.floor((basePrice - (basePrice * discount / 100)) * 100) / 100 : basePrice;
}
}
if (!priceToSend && ctx.priceNode) {
priceToSend = _parsePriceText(ctx.priceNode.textContent);
}
await window.ecomGlobalScripts.functions.addToCart({
entryType: entryType,
code: code,
codIdioma: codIdioma,
codFormato: codFormato,
price: priceToSend,
name: name,
amount: qty
});
};
const helper = window.ecomGlobalScripts?.functions?.withButtonSpinner;
if (typeof helper === "function") {
return helper(btn, run, { spinnerClass: "spinner-border spinner-border-sm text-light", mode: "replace" });
}
return run();
});
});
};
const _DOMContentLoaded = async function() {
//Event DOMContentLoaded
if (publicProps.isDebug) console.log("DOMContentLoaded ecom Generic scripts");
if (publicProps.isDebug) console.log("DOMContentLoaded ecom Generic scripts - _loadInit execute");
await _loadInit();
await _attachDetailAddToCart();
};
// ---- Execute Listener DOMContentLoaded ----
document.addEventListener("DOMContentLoaded", async function() {
await _DOMContentLoaded();
});
/* =====================================
API PÚBLICA
===================================== */
return {
properties: publicProps, // properties public
functions: functions // functions public
};
})();
BS EN 16771:2016
Railway applications. Infrastructure. Aluminothermic welding of grooved rails
| Fecha edición: |
2016-11-30
En Vigor
|
|---|---|
| Idiomas disponibles: | Inglés |
| Resumen: | This standard defines the laboratory tests and requirements for approval of an aluminothermic welding process using welds produced in workshop conditions. It applies to the joining of new, grooved rails as described in EN 14811 of the same profile and steel grade. Welding of construction profiles and machined profiles are not covered in this standard. Compliance with the requirements of this standard does not in itself ensure the suitability of a welding process for specific conditions of track and traffic. The standard does not cover welds made between different rail sections, worn rails or different rail grades. In addition to the definitive requirements, this standard also requires the items detailed in Clause 4 to be documented. For compliance with this standard, it is important that both the definitive requirements and the documented items be satisfied. |
| ICS: | |
| CTN: | RAE/2 - RAE/2 |
|
Equivalencia Internacional |
Idéntica EN 16771:2016 |










