/* ===== Tipografías alojadas en el propio servidor (sin Google Fonts: Google está bloqueado en China) =====
   Archivo (variable: grosor y ancho) para títulos y Outfit (variable) para texto. Subconjunto latin:
   cubre español, inglés y portugués. El chino usa fuentes del sistema (ver reglas html[lang="zh"]). */
@font-face{
  font-family:"Archivo"; font-style:normal; font-weight:100 900; font-stretch:62% 125%; font-display:swap;
  src:url("../fonts/archivo-wdth-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Outfit"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("../fonts/outfit-latin.woff2") format("woff2");
}

/* ============================================================
   VOLT — Design system v3
   Paleta OFICIAL: muestreada directamente del logo real entregado por el
   cliente (las dos montañas del isotipo + el café de la palabra "VOLT").
     verde-oliva  #9BC53B  (montaña izquierda — color principal 1)
     naranja      #217139  (montaña derecha — color principal 2)
     café marca   #2E6B4C  (color de la palabra "VOLT" — acento secundario)
     espresso     #0B2B20  (neutro oscuro, derivado del café de marca)
   Regla de aplicación: los dos colores del isotipo (oliva + naranja) son los
   dominantes; el café de la palabra se usa como acento secundario puntual.
   El espresso es el neutro oscuro (texto, header, footer) — no un cuarto color compitiendo.
   Tipografía: Manrope única familia, contraste por peso (800 display / 400-600 texto).
   Composición de hero: calcada de Olam Agri (bloque de color + foto en diagonal + texto fantasma).
   ============================================================ */

:root{
  --m-hojas:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 372 357%22 width=%22372%22 height=%22357%22%3E%3Cpath fill=%22%23000%22 fill-rule=%22evenodd%22 d=%22M48.25 179.38C47.31 180.48 46.73 182.17 45.88 183.38C45.02 184.58 44.62 184.33 43.12 186.62C41.62 188.92 38.56 194.06 36.88 197.12C35.19 200.19 34.31 201.92 33.00 205.00C31.69 208.08 30.00 212.48 29.00 215.62C28.00 218.77 27.35 221.83 27.00 223.88C26.65 225.92 27.06 226.46 26.88 227.88C26.69 229.29 26.04 230.15 25.88 232.38C25.71 234.60 25.71 239.21 25.88 241.25C26.04 243.29 26.69 243.25 26.88 244.62C27.06 246.00 26.67 247.69 27.00 249.50C27.33 251.31 28.56 254.15 28.88 255.50C29.19 256.85 28.73 257.08 28.88 257.62C29.02 258.17 29.10 257.10 29.75 258.75C30.40 260.40 31.92 265.54 32.75 267.50C33.58 269.46 33.85 268.81 34.75 270.50C35.65 272.19 36.48 274.83 38.12 277.62C39.77 280.42 42.50 284.44 44.62 287.25C46.75 290.06 49.73 293.06 50.88 294.50C52.02 295.94 49.75 293.92 51.50 295.88C53.25 297.83 57.73 302.77 61.38 306.25C65.02 309.73 70.52 314.44 73.38 316.75C76.23 319.06 77.21 319.10 78.50 320.12C79.79 321.15 79.21 321.44 81.12 322.88C83.04 324.31 87.94 327.54 90.00 328.75C92.06 329.96 91.44 328.98 93.50 330.12C95.56 331.27 99.08 333.83 102.38 335.62C105.67 337.42 107.75 338.65 113.25 340.88C118.75 343.10 131.38 347.65 135.38 349.00C139.38 350.35 136.62 348.83 137.25 349.00C137.88 349.17 138.48 349.83 139.12 350.00C139.77 350.17 140.56 349.85 141.12 350.00C141.69 350.15 141.88 350.69 142.50 350.88C143.12 351.06 144.19 350.94 144.88 351.12C145.56 351.31 145.92 351.85 146.62 352.00C147.33 352.15 148.35 351.83 149.12 352.00C149.90 352.17 150.40 352.83 151.25 353.00C152.10 353.17 153.40 352.83 154.25 353.00C155.10 353.17 155.40 353.83 156.38 354.00C157.35 354.17 159.10 353.83 160.12 354.00C161.15 354.17 161.40 354.83 162.50 355.00C163.60 355.17 165.33 354.85 166.75 355.00C168.17 355.15 165.04 355.73 171.00 355.88C176.96 356.02 196.83 356.00 202.50 355.88C208.17 355.75 203.71 355.27 205.00 355.12C206.29 354.98 209.04 355.17 210.25 355.00C211.46 354.83 211.19 354.31 212.25 354.12C213.31 353.94 215.62 354.06 216.62 353.88C217.62 353.69 217.46 353.17 218.25 353.00C219.04 352.83 220.54 353.04 221.38 352.88C222.21 352.71 222.56 352.15 223.25 352.00C223.94 351.85 224.88 352.15 225.50 352.00C226.12 351.85 226.35 351.27 227.00 351.12C227.65 350.98 228.73 351.29 229.38 351.12C230.02 350.96 229.83 350.50 230.88 350.12C231.92 349.75 234.67 349.23 235.62 348.88C236.58 348.52 236.12 348.15 236.62 348.00C237.12 347.85 237.88 348.17 238.62 348.00C239.38 347.83 240.23 347.46 241.12 347.00C242.02 346.54 243.40 345.71 244.00 345.25C244.60 344.79 244.60 344.69 244.75 344.25C244.90 343.81 245.17 343.21 244.88 342.62C244.58 342.04 243.81 341.19 243.00 340.75C242.19 340.31 241.85 340.12 240.00 340.00C238.15 339.88 234.81 340.50 231.88 340.00C228.94 339.50 224.29 337.52 222.38 337.00C220.46 336.48 222.38 337.54 220.38 336.88C218.38 336.21 212.33 333.67 210.38 333.00C208.42 332.33 209.31 333.19 208.62 332.88C207.94 332.56 207.94 331.96 206.25 331.12C204.56 330.29 200.92 329.06 198.50 327.88C196.08 326.69 194.96 326.23 191.75 324.00C188.54 321.77 181.85 316.58 179.25 314.50C176.65 312.42 176.81 312.35 176.12 311.50C175.44 310.65 176.40 310.85 175.12 309.38C173.85 307.90 170.65 305.08 168.50 302.62C166.35 300.17 164.81 298.50 162.25 294.62C159.69 290.75 155.71 284.00 153.12 279.38C150.54 274.75 148.21 269.54 146.75 266.88C145.29 264.21 144.88 264.33 144.38 263.38C143.88 262.42 144.29 262.10 143.75 261.12C143.21 260.15 142.12 259.21 141.12 257.50C140.12 255.79 139.23 253.19 137.75 250.88C136.27 248.56 134.08 246.29 132.25 243.62C130.42 240.96 128.44 237.06 126.75 234.88C125.06 232.69 123.02 231.46 122.12 230.50C121.23 229.54 123.46 231.21 121.38 229.12C119.29 227.04 111.81 219.94 109.62 218.00C107.44 216.06 108.94 218.02 108.25 217.50C107.56 216.98 106.17 215.35 105.50 214.88C104.83 214.40 104.75 214.96 104.25 214.62C103.75 214.29 103.75 213.79 102.50 212.88C101.25 211.96 99.00 210.44 96.75 209.12C94.50 207.81 91.71 206.23 89.00 205.00C86.29 203.77 82.42 202.58 80.50 201.75C78.58 200.92 78.38 200.31 77.50 200.00C76.62 199.69 76.02 200.06 75.25 199.88C74.48 199.69 73.94 199.08 72.88 198.88C71.81 198.67 69.92 198.60 68.88 198.62C67.83 198.65 67.29 198.69 66.62 199.00C65.96 199.31 65.29 199.73 64.88 200.50C64.46 201.27 64.12 202.65 64.12 203.62C64.12 204.60 64.73 205.12 64.88 206.38C65.02 207.62 64.85 210.10 65.00 211.12C65.15 212.15 65.29 210.15 65.75 212.50C66.21 214.85 66.56 220.38 67.75 225.25C68.94 230.12 72.02 238.73 72.88 241.75C73.73 244.77 72.98 243.06 72.88 243.38C72.77 243.69 73.02 244.58 72.25 243.62C71.48 242.67 69.62 240.15 68.25 237.62C66.88 235.10 65.35 231.96 64.00 228.50C62.65 225.04 61.46 222.00 60.12 216.88C58.79 211.75 56.88 202.52 56.00 197.75C55.12 192.98 55.08 191.48 54.88 188.25C54.67 185.02 54.96 180.23 54.75 178.38C54.54 176.52 54.17 177.40 53.62 177.12C53.08 176.85 52.40 176.38 51.50 176.75C50.60 177.12 49.19 178.27 48.25 179.38ZM363.12 131.00C362.71 130.81 361.96 130.60 361.38 130.88C360.79 131.15 360.40 130.90 359.62 132.62C358.85 134.35 357.44 139.48 356.75 141.25C356.06 143.02 356.00 141.52 355.50 143.25C355.00 144.98 354.40 149.35 353.75 151.62C353.10 153.90 352.46 155.19 351.62 156.88C350.79 158.56 349.27 160.52 348.75 161.75C348.23 162.98 348.69 163.52 348.50 164.25C348.31 164.98 348.04 165.52 347.62 166.12C347.21 166.73 346.52 166.98 346.00 167.88C345.48 168.77 346.27 168.73 344.50 171.50C342.73 174.27 338.19 181.12 335.38 184.50C332.56 187.88 329.48 190.17 327.62 191.75C325.77 193.33 324.98 193.38 324.25 194.00C323.52 194.62 323.90 195.04 323.25 195.50C322.60 195.96 321.75 195.88 320.38 196.75C319.00 197.62 316.54 199.83 315.00 200.75C313.46 201.67 312.35 201.56 311.12 202.25C309.90 202.94 309.69 203.81 307.62 204.88C305.56 205.94 300.69 207.67 298.75 208.62C296.81 209.58 297.52 209.94 296.00 210.62C294.48 211.31 291.06 212.10 289.62 212.75C288.19 213.40 288.48 214.02 287.38 214.50C286.27 214.98 284.19 215.06 283.00 215.62C281.81 216.19 281.15 217.42 280.25 217.88C279.35 218.33 279.23 217.65 277.62 218.38C276.02 219.10 272.58 221.29 270.62 222.25C268.67 223.21 268.33 222.79 265.88 224.12C263.42 225.46 257.85 229.12 255.88 230.25C253.90 231.38 254.77 230.29 254.00 230.88C253.23 231.46 252.42 232.85 251.25 233.75C250.08 234.65 248.69 235.02 247.00 236.25C245.31 237.48 244.00 238.35 241.12 241.12C238.25 243.90 232.56 249.75 229.75 252.88C226.94 256.00 225.40 258.29 224.25 259.88C223.10 261.46 223.40 261.69 222.88 262.38C222.35 263.06 222.56 261.81 221.12 264.00C219.69 266.19 216.08 271.85 214.25 275.50C212.42 279.15 211.10 282.94 210.12 285.88C209.15 288.81 208.40 291.62 208.38 293.12C208.35 294.62 209.27 294.40 210.00 294.88C210.73 295.35 211.46 295.81 212.75 296.00C214.04 296.19 216.29 296.15 217.75 296.00C219.21 295.85 220.02 295.29 221.50 295.12C222.98 294.96 224.10 295.50 226.62 295.00C229.15 294.50 234.48 292.65 236.62 292.12C238.77 291.60 238.17 292.23 239.50 291.88C240.83 291.52 242.73 290.52 244.62 290.00C246.52 289.48 249.44 288.94 250.88 288.75C252.31 288.56 253.62 288.35 253.25 288.88C252.88 289.40 253.21 290.08 248.62 291.88C244.04 293.67 232.71 297.69 225.75 299.62C218.79 301.56 212.58 302.65 206.88 303.50C201.17 304.35 194.21 304.25 191.50 304.75C188.79 305.25 190.44 305.56 190.62 306.50C190.81 307.44 191.60 309.15 192.62 310.38C193.65 311.60 195.10 312.75 196.75 313.88C198.40 315.00 201.25 316.27 202.50 317.12C203.75 317.98 203.44 318.50 204.25 319.00C205.06 319.50 206.00 319.42 207.38 320.12C208.75 320.83 209.71 321.96 212.50 323.25C215.29 324.54 220.77 326.75 224.12 327.88C227.48 329.00 230.40 329.60 232.62 330.00C234.85 330.40 236.04 330.04 237.50 330.25C238.96 330.46 239.71 330.98 241.38 331.25C243.04 331.52 245.40 331.77 247.50 331.88C249.60 331.98 252.38 332.00 254.00 331.88C255.62 331.75 256.08 331.25 257.25 331.12C258.42 331.00 258.73 331.44 261.00 331.12C263.27 330.81 268.06 329.92 270.88 329.25C273.69 328.58 275.75 327.94 277.88 327.12C280.00 326.31 282.21 324.96 283.62 324.38C285.04 323.79 285.60 324.00 286.38 323.62C287.15 323.25 287.50 322.54 288.25 322.12C289.00 321.71 290.04 321.62 290.88 321.12C291.71 320.62 292.21 319.73 293.25 319.12C294.29 318.52 294.90 318.85 297.12 317.50C299.35 316.15 302.19 314.67 306.62 311.00C311.06 307.33 318.58 300.79 323.75 295.50C328.92 290.21 333.46 284.81 337.62 279.25C341.79 273.69 346.48 265.81 348.75 262.12C351.02 258.44 350.62 258.65 351.25 257.12C351.88 255.60 351.79 254.42 352.50 253.00C353.21 251.58 354.85 250.00 355.50 248.62C356.15 247.25 355.62 246.71 356.38 244.75C357.12 242.79 358.42 241.48 360.00 236.88C361.58 232.27 364.81 221.12 365.88 217.12C366.94 213.12 366.10 213.96 366.38 212.88C366.65 211.79 366.85 214.79 367.50 210.62C368.15 206.46 369.75 195.94 370.25 187.88C370.75 179.81 370.88 168.94 370.50 162.25C370.12 155.56 368.88 151.62 368.00 147.75C367.12 143.88 365.94 141.62 365.25 139.00C364.56 136.38 364.23 133.33 363.88 132.00C363.52 130.67 363.54 131.19 363.12 131.00ZM178.50 45.50C176.92 44.06 175.79 43.19 174.00 42.00C172.21 40.81 170.31 39.69 167.75 38.38C165.19 37.06 161.96 35.52 158.62 34.12C155.29 32.73 151.29 31.04 147.75 30.00C144.21 28.96 140.85 28.40 137.38 27.88C133.90 27.35 131.65 26.85 126.88 26.88C122.10 26.90 113.42 27.33 108.75 28.00C104.08 28.67 101.50 30.21 98.88 30.88C96.25 31.54 94.73 31.33 93.00 32.00C91.27 32.67 90.50 33.90 88.50 34.88C86.50 35.85 82.54 37.08 81.00 37.88C79.46 38.67 80.04 39.15 79.25 39.62C78.46 40.10 77.12 40.19 76.25 40.75C75.38 41.31 75.25 42.10 74.00 43.00C72.75 43.90 70.31 45.04 68.75 46.12C67.19 47.21 67.71 46.65 64.62 49.50C61.54 52.35 53.65 59.77 50.25 63.25C46.85 66.73 46.31 67.67 44.25 70.38C42.19 73.08 39.29 77.62 37.88 79.50C36.46 81.38 36.25 80.92 35.75 81.62C35.25 82.33 35.35 83.04 34.88 83.75C34.40 84.46 33.92 84.27 32.88 85.88C31.83 87.48 29.69 91.69 28.62 93.38C27.56 95.06 27.02 95.06 26.50 96.00C25.98 96.94 26.23 97.52 25.50 99.00C24.77 100.48 23.40 102.23 22.12 104.88C20.85 107.52 18.79 112.92 17.88 114.88C16.96 116.83 18.15 112.21 16.62 116.62C15.10 121.04 10.19 136.23 8.75 141.38C7.31 146.52 8.50 145.19 8.00 147.50C7.50 149.81 6.23 152.81 5.75 155.25C5.27 157.69 5.42 160.08 5.12 162.12C4.83 164.17 4.29 164.33 4.00 167.50C3.71 170.67 3.38 175.69 3.38 181.12C3.38 186.56 3.62 195.17 4.00 200.12C4.38 205.08 4.62 206.88 5.62 210.88C6.62 214.88 9.02 221.56 10.00 224.12C10.98 226.69 10.94 225.83 11.50 226.25C12.06 226.67 12.62 227.19 13.38 226.62C14.12 226.06 15.08 224.81 16.00 222.88C16.92 220.94 18.17 217.54 18.88 215.00C19.58 212.46 19.35 210.79 20.25 207.62C21.15 204.46 22.44 199.83 24.25 196.00C26.06 192.17 28.65 188.23 31.12 184.62C33.60 181.02 36.88 176.96 39.12 174.38C41.38 171.79 43.23 170.33 44.62 169.12C46.02 167.92 46.77 167.79 47.50 167.12C48.23 166.46 47.60 166.19 49.00 165.12C50.40 164.06 54.25 161.90 55.88 160.75C57.50 159.60 56.50 159.67 58.75 158.25C61.00 156.83 65.94 154.02 69.38 152.25C72.81 150.48 77.42 148.65 79.38 147.62C81.33 146.60 80.46 146.42 81.12 146.12C81.79 145.83 82.56 146.21 83.38 145.88C84.19 145.54 83.10 145.42 86.00 144.12C88.90 142.83 96.54 139.98 100.75 138.12C104.96 136.27 106.79 135.54 111.25 133.00C115.71 130.46 124.00 125.15 127.50 122.88C131.00 120.60 130.29 121.04 132.25 119.38C134.21 117.71 137.31 114.81 139.25 112.88C141.19 110.94 142.94 108.94 143.88 107.75C144.81 106.56 144.25 106.52 144.88 105.75C145.50 104.98 146.42 104.69 147.62 103.12C148.83 101.56 149.56 100.67 152.12 96.38C154.69 92.08 161.02 81.21 163.00 77.38C164.98 73.54 163.81 74.85 164.00 73.38C164.19 71.90 163.98 69.81 164.12 68.50C164.27 67.19 164.98 66.42 164.88 65.50C164.77 64.58 164.06 63.60 163.50 63.00C162.94 62.40 162.12 62.08 161.50 61.88C160.88 61.67 161.69 61.44 159.75 61.75C157.81 62.06 152.12 63.40 149.88 63.75C147.62 64.10 147.48 63.56 146.25 63.88C145.02 64.19 143.58 65.29 142.50 65.62C141.42 65.96 141.02 65.52 139.75 65.88C138.48 66.23 137.71 67.02 134.88 67.75C132.04 68.48 124.90 69.88 122.75 70.25C120.60 70.62 122.19 70.19 122.00 70.00C121.81 69.81 121.54 69.42 121.62 69.12C121.71 68.83 121.23 68.85 122.50 68.25C123.77 67.65 127.62 66.04 129.25 65.50C130.88 64.96 130.81 65.52 132.25 65.00C133.69 64.48 134.73 63.52 137.88 62.38C141.02 61.23 147.44 59.17 151.12 58.12C154.81 57.08 157.50 56.46 160.00 56.12C162.50 55.79 162.12 56.56 166.12 56.12C170.12 55.69 180.96 54.12 184.00 53.50C187.04 52.88 184.46 52.85 184.38 52.38C184.29 51.90 184.48 51.77 183.50 50.62C182.52 49.48 180.08 46.94 178.50 45.50ZM127.12 14.25C126.65 14.90 126.54 15.15 127.00 15.75C127.46 16.35 129.00 17.50 129.88 17.88C130.75 18.25 131.56 17.83 132.25 18.00C132.94 18.17 132.85 18.56 134.00 18.88C135.15 19.19 137.56 19.69 139.12 19.88C140.69 20.06 142.40 19.83 143.38 20.00C144.35 20.17 144.08 20.69 145.00 20.88C145.92 21.06 147.83 20.94 148.88 21.12C149.92 21.31 150.33 21.85 151.25 22.00C152.17 22.15 153.54 21.85 154.38 22.00C155.21 22.15 155.46 22.71 156.25 22.88C157.04 23.04 158.44 22.83 159.12 23.00C159.81 23.17 159.33 23.54 160.38 23.88C161.42 24.21 164.38 24.67 165.38 25.00C166.38 25.33 165.94 25.69 166.38 25.88C166.81 26.06 166.48 25.52 168.00 26.12C169.52 26.73 173.98 28.69 175.50 29.50C177.02 30.31 176.31 30.54 177.12 31.00C177.94 31.46 178.33 31.08 180.38 32.25C182.42 33.42 186.65 35.96 189.38 38.00C192.10 40.04 193.90 41.60 196.75 44.50C199.60 47.40 204.62 53.02 206.50 55.38C208.38 57.73 207.12 57.31 208.00 58.62C208.88 59.94 209.98 60.62 211.75 63.25C213.52 65.88 217.46 72.33 218.62 74.38C219.79 76.42 217.90 73.92 218.75 75.50C219.60 77.08 222.85 82.21 223.75 83.88C224.65 85.54 223.65 84.56 224.12 85.50C224.60 86.44 225.27 86.85 226.62 89.50C227.98 92.15 229.85 96.90 232.25 101.38C234.65 105.85 238.73 112.85 241.00 116.38C243.27 119.90 244.83 121.04 245.88 122.50C246.92 123.96 245.88 123.38 247.25 125.12C248.62 126.88 251.60 130.38 254.12 133.00C256.65 135.62 259.94 138.81 262.38 140.88C264.81 142.94 266.27 143.85 268.75 145.38C271.23 146.90 275.67 149.06 277.25 150.00C278.83 150.94 274.98 149.50 278.25 151.00C281.52 152.50 293.42 157.65 296.88 159.00C300.33 160.35 298.35 158.96 299.00 159.12C299.65 159.29 299.44 159.83 300.75 160.00C302.06 160.17 305.48 160.42 306.88 160.12C308.27 159.83 308.62 158.92 309.12 158.25C309.62 157.58 309.75 156.83 309.88 156.12C310.00 155.42 310.04 155.06 309.88 154.00C309.71 152.94 309.21 152.06 308.88 149.75C308.54 147.44 308.35 142.62 307.88 140.12C307.40 137.62 306.31 135.92 306.00 134.75C305.69 133.58 306.33 134.19 306.00 133.12C305.67 132.06 304.35 129.65 304.00 128.38C303.65 127.10 304.35 127.35 303.88 125.50C303.40 123.65 301.58 118.81 301.12 117.25C300.67 115.69 301.00 116.35 301.12 116.12C301.25 115.90 301.06 114.79 301.88 115.88C302.69 116.96 304.67 120.21 306.00 122.62C307.33 125.04 308.40 127.04 309.88 130.38C311.35 133.71 314.04 140.33 314.88 142.62C315.71 144.92 314.38 142.35 314.88 144.12C315.38 145.90 317.21 150.81 317.88 153.25C318.54 155.69 318.71 157.23 318.88 158.75C319.04 160.27 318.69 160.85 318.88 162.38C319.06 163.90 319.79 165.02 320.00 167.88C320.21 170.73 320.04 177.50 320.12 179.50C320.21 181.50 320.04 179.85 320.50 179.88C320.96 179.90 321.50 180.65 322.88 179.62C324.25 178.60 326.77 176.10 328.75 173.75C330.73 171.40 333.04 168.12 334.75 165.50C336.46 162.88 337.48 161.10 339.00 158.00C340.52 154.90 342.75 149.75 343.88 146.88C345.00 144.00 345.06 143.71 345.75 140.75C346.44 137.79 347.62 133.27 348.00 129.12C348.38 124.98 348.17 119.15 348.00 115.88C347.83 112.60 347.52 111.98 347.00 109.50C346.48 107.02 345.58 103.42 344.88 101.00C344.17 98.58 343.79 97.48 342.75 95.00C341.71 92.52 340.10 89.02 338.62 86.12C337.15 83.23 335.50 80.27 333.88 77.62C332.25 74.98 331.38 73.58 328.88 70.25C326.38 66.92 323.25 62.33 318.88 57.62C314.50 52.92 308.50 46.77 302.62 42.00C296.75 37.23 288.23 31.98 283.62 29.00C279.02 26.02 277.88 25.62 275.00 24.12C272.12 22.62 268.42 20.88 266.38 20.00C264.33 19.12 263.92 19.40 262.75 18.88C261.58 18.35 260.56 17.38 259.38 16.88C258.19 16.38 257.83 16.71 255.62 15.88C253.42 15.04 249.10 12.88 246.12 11.88C243.15 10.88 239.38 10.38 237.75 9.88C236.12 9.38 236.92 9.04 236.38 8.88C235.83 8.71 235.06 9.02 234.50 8.88C233.94 8.73 233.62 8.17 233.00 8.00C232.38 7.83 231.50 8.06 230.75 7.88C230.00 7.69 230.15 7.21 228.50 6.88C226.85 6.54 222.48 6.19 220.88 5.88C219.27 5.56 219.96 5.17 218.88 5.00C217.79 4.83 215.54 5.04 214.38 4.88C213.21 4.71 212.92 4.15 211.88 4.00C210.83 3.85 209.50 4.17 208.12 4.00C206.75 3.83 206.31 3.19 203.62 3.00C200.94 2.81 194.29 3.02 192.00 2.88C189.71 2.73 193.90 2.10 189.88 2.12C185.85 2.15 171.96 2.71 167.88 3.00C163.79 3.29 166.71 3.71 165.38 3.88C164.04 4.04 161.19 3.83 159.88 4.00C158.56 4.17 158.58 4.71 157.50 4.88C156.42 5.04 154.35 4.83 153.38 5.00C152.40 5.17 153.10 5.56 151.62 5.88C150.15 6.19 145.88 6.56 144.50 6.88C143.12 7.19 144.54 7.40 143.38 7.75C142.21 8.10 138.69 8.65 137.50 9.00C136.31 9.35 136.75 9.71 136.25 9.88C135.75 10.04 135.56 9.67 134.50 10.00C133.44 10.33 131.10 11.17 129.88 11.88C128.65 12.58 127.60 13.60 127.12 14.25Z%22/%3E%3C/svg%3E");
  --gold: #9BC53B;
  --gold-light: #B5D96A;
  --gold-pale: #EAF3D6;
  --terracotta: #217139;
  --terracotta-dark: #0A5A3A;
  --espresso: #0B2B20;
  --espresso-soft: #2E6B4C;
  --cream: #F8FBF3;
  --cream-2: #D3DDC6;
  --ink: #0B2B20;
  --ink-soft: #55675C;
  --line: rgba(11,43,32,.13);
  --line-strong: rgba(11,43,32,.24);
  --white: #ffffff;

  --display: "Archivo", "Segoe UI", sans-serif;
  --sans: "Outfit", "Segoe UI", sans-serif;

  /* Antes 1600px: en monitores anchos (>1700px) el contenido llegaba casi
     al borde de la ventana, con muy poco aire a los costados. 1320px deja
     un margen visible y proporcional en escritorio sin afectar tablet/mobile
     (ahí el viewport ya es más angosto que esto, así que no cambia nada). */
  --container: 1320px;
  --radius: 8px;
  --ease: cubic-bezier(.22,.8,.28,1);
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; overflow-x:clip; }
/* .contact-band usa el truco width:100vw para salirse del container y ser
   ancho completo real — pero 100vw incluye el ancho de la scrollbar vertical,
   así que sin recortar esto esa sección se pasaba unos px del borde derecho y
   generaba scroll horizontal en toda la página. Usamos overflow-x:CLIP (no
   "hidden"): "hidden" convierte a html/body en un contenedor de scroll propio,
   y eso es justo lo que rompía el header "sticky" — a ratos perdía su punto
   de referencia y desaparecía por completo al hacer scroll. "clip" recorta
   igual mostrando el borde, pero sin crear ese contenedor de scroll. */
body{
  margin:0; background:var(--cream); color:var(--ink);
  font-family:var(--sans); font-size:16px; line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
}
img{ max-width:100%; height:auto; display:block; } /* height:auto: con width/height en las etiquetas <img>, el navegador reserva el espacio por proporción sin deformar; cualquier regla de clase con alto propio lo sustituye */
a{ color:inherit; text-decoration:none; }
ul{ margin:0; padding:0; list-style:none; }
button{ font-family:inherit; cursor:pointer; background:none; border:0; }
.container{ max-width:var(--container); margin:0 auto; padding:0 44px; }
section{ position:relative; }
@media (prefers-reduced-motion: reduce){
  *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
}

h1,h2,h3{ font-family:var(--display); font-weight:800; color:var(--espresso); margin:0; letter-spacing:-.01em; }
.accent-word{ color:var(--terracotta); }

.eyebrow{
  display:inline-flex; align-items:center; gap:10px;
  font-size:15px; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
  color:var(--terracotta-dark);
}
.eyebrow::before{ content:""; width:22px; height:2px; background:var(--terracotta); display:inline-block; }

/* --i (asignado en JS a cada .reveal, 0–7 repitiendo) antes se guardaba pero
   nunca se usaba en el CSS — todos los elementos de una fila (las 3 puertas,
   los 4 puntos de servicios, etc.) aparecían exactamente al mismo instante,
   en bloque, sin cascada — eso se sentía golpeado/espontáneo. Con el delay
   escalonado por --i, entran uno tras otro, más fluido.
   Bug real encontrado: las puertas, los puntos de servicios y la foto de
   servicios NO se animaban en absoluto — cada uno tiene su PROPIA regla
   `transition` (para el hover: sombra, esquina, fondo...) que, al venir
   después en la hoja de estilos, reemplazaba por completo la `transition` de
   `.reveal` sobre el mismo elemento (con el mismo selector no se combinan,
   se pisan). Por eso usamos la propiedad `translate` (aparte de `transform`,
   que es la que usa cada hover) — así nunca chocan, sin importar qué
   elemento sea. */
.reveal{
  opacity:0; translate:0 26px;
  transition:opacity .6s var(--ease), translate .6s var(--ease);
  transition-delay:calc(var(--i, 0) * 55ms);
}
.reveal.in{ opacity:1; translate:none; }

/* Caso especial: Contacto. En vez de desvanecerse desde la nada, se pidió
   que se sienta como si "saliera de atrás del pie de página" — se mantiene
   siempre visible (sin fade) y solo se desplaza hacia arriba desde abajo. */
.contact-band.reveal{ opacity:1; translate:0 80px; transition:translate .85s var(--ease); }
.contact-band.reveal.in{ translate:none; }

/* Línea/costura tenue reportada entre Contacto y el pie de página SOLO en
   mobile: dos bloques del mismo color (espresso) pegados, uno de ellos
   animado con `translate` — cuando ese `translate` queda "activo" aunque
   sea en 0 0, el navegador lo sigue tratando como una capa aparte y a veces
   se nota un filo de 1px en la costura por el antialiasing de esa capa.
   `translate:none` evita dejar esa capa prendida en reposo, y este ligero
   solape negativo tapa cualquier resto de esa costura sin afectar el hueco
   de arriba (que va en el padding, no en el margen). */
.contact-band{ margin-bottom:-1px; }

/* Firma visual del sitio: una sola esquina con radio grande y curvo (suavizada), el resto en escuadra —
   el mismo recurso que Olam usa en sus fotos y bloques. Se repite en paneles y fotos del sitio. */
.corner-cut{ border-radius:0 var(--corner,64px) 0 0; }

/* ============ UTILITY BAR ============ */
/* Se encoge a 0 (altura + opacidad) al hacer scroll — así "se desliza y desaparece"
   sin necesitar overflow:hidden en el grupo completo (eso recortaba el mega menú). */
.util-bar{
  background:var(--espresso); color:rgba(247,251,240,.78); font-size:15.75px;
  overflow:hidden; height:52px; transition:height .5s cubic-bezier(.4,0,.2,1), opacity .4s ease;
}
.header-group.scrolled .util-bar{ height:0; opacity:0; }
.header-group.menu-open .util-bar{ height:0; opacity:0; transition-duration:.25s; }
.util-bar-inner{ display:flex; align-items:center; justify-content:space-between; height:52px; }
.util-links{ display:flex; align-items:center; gap:28px; }
.util-links a, .util-links button{ display:flex; align-items:center; gap:8px; color:inherit; font-size:15.75px; font-weight:600; transition:color .2s; }
.util-links a:hover, .util-links button:hover{ color:var(--gold-light); }
.util-links svg{ width:17px; height:17px; }
.util-right{ display:flex; align-items:center; gap:22px; }
.util-lang{ display:flex; gap:3px; }
.util-lang button{ padding:2px 6px; font-weight:700; color:rgba(247,251,240,.6); font-size:15.3px; }
.util-lang button.active{ color:var(--gold-light); }
.util-lang span{ color:rgba(247,251,240,.3); }
/* Banderas reales (no íconos/stickers genéricos) en vez del texto "/" como
   separador — una por idioma, recortadas a proporción bandera (3:2) con una
   línea sutil alrededor para que no se pierdan sobre el fondo oscuro del
   header cuando la bandera tiene blanco en el borde (ej. la de EN). */
.lang-btn{ display:flex; align-items:center; gap:5px; }
.lang-flag{ width:18px; height:12px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 1px rgba(247,251,240,.25); flex:0 0 auto; }
.util-subscribe{ background:var(--terracotta); color:var(--cream); font-weight:800; font-size:15.3px; padding:10px 20px; display:flex; align-items:center; gap:9px; transition:background .25s; }
.util-subscribe:hover{ background:var(--terracotta-dark); }
.util-subscribe svg{ width:16px; height:16px; }

/* ============ HEADER ============ */
/* La utilidad y el nav viajan juntos en un solo grupo. Al hacer scroll, la barra
   utilitaria se encoge a 0 (arriba) y el nav queda ocupando el tope — coreografía real,
   no solo un cambio de color. Sin overflow:hidden aquí: el mega menú necesita poder
   desbordar hacia abajo del header sin que nada lo recorte. */
/* position:fixed (antes era sticky) a propósito: con sticky, el header sigue
   ocupando espacio real en el flujo del documento con SU TAMAÑO ACTUAL — así
   que cuando la barra utilitaria se encoge (52px→0px) el propio header-group
   se vuelve 52px más bajo, y TODO lo que viene después (el Hero de página
   interior, y cualquier contenido debajo) se recorre hacia arriba ese mismo
   tanto — un "salto"/rebote visible confirmado con video real, en todas las
   páginas interiores (index.html no lo sufría porque su Hero ya es fixed,
   fuera del flujo). Con fixed, el header-group sale COMPLETAMENTE del flujo:
   ya no importa cuánto cambie su propio alto, nunca empuja ni recorre nada
   de lo que sigue. La contraparte: cada página tiene que reservar a mano el
   espacio que el header YA NO reserva solo — ver el padding-top fijo en
   .page-hero (interior) y .hero-inner (home), ambos ya preparados para esto.
   overflow-anchor:none evita el bug real detrás del parpadeo/saltitos: al
   encoger la barra utilitaria (52px→0), el navegador (Chrome de forma
   automática) intenta "anclar" el scroll para compensar ese movimiento de
   layout — pero esa compensación puede cruzar de nuevo el umbral que prende
   el estado "scrolled", encogiendo/agrandando el header en loop. Esto le
   dice al navegador que no toque el scroll por los cambios de tamaño aquí. */
.header-group{ position:fixed; top:0; left:0; right:0; z-index:100; overflow-anchor:none; }

.site-header{
  position:relative;
  background:var(--cream);
  border-bottom:1px solid transparent; transition:background .35s var(--ease), border-color .3s, box-shadow .3s;
}
.site-header.scrolled{ border-color:var(--line); box-shadow:0 6px 24px rgba(11,43,32,.06); }
.site-header .container{ position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between; height:82px; }

/* ---- Home: header transparente flotando sobre el hero, se vuelve sólido al hacer scroll ---- */
body.home .site-header{
  background:transparent; border-bottom:0; box-shadow:none;
}
/* El fondo oscuro ya no es un simple cambio de color: es una capa aparte que
   se revela con un barrido de arriba hacia abajo (clip-path inset, borde
   inferior animado) — como una cortina que cae — en vez de aparecer/perderse
   de golpe. Vive en su propio pseudo-elemento para no interferir con el
   mega menú, que necesita poder desbordar por debajo del header.
   Ya NO vive dentro de `body.home`: antes este barrido solo pasaba en el
   home — en las páginas interiores el header se quedaba siempre en su
   versión clara (crema) al hacer scroll, sin el cambio a oscuro. Sacar el
   pseudo-elemento de `body.home` lo crea en TODAS las páginas (sigue oculto
   por defecto, clip-path:inset(0 0 100% 0)); el barrido en sí solo se activa
   con `.scrolled` más abajo, así que en reposo no cambia nada visualmente en
   ninguna página. */
.site-header::before{
  content:""; position:absolute; inset:0; z-index:0;
  background:var(--espresso);
  clip-path:inset(0 0 100% 0);
  transition:clip-path 1.05s var(--ease);
  pointer-events:none;
}
body.home .site-header .brand-word{ color:var(--cream); transition:color .35s var(--ease); }
body.home .site-header .brand-mark{ filter:brightness(0) invert(1); transition:filter .35s var(--ease); }
/* El logo (brand-word/brand-mark) ya era crema/blanco incluso sin scroll —
   señal de que esta franja de arriba SIEMPRE cae sobre fondo oscuro (la curva
   naranja del hero, no una zona clara), nunca sobre algo parecido al fondo
   crema de las páginas interiores. Un intento anterior puso el nav en tonos
   oscuros (espresso) ahí mismo, y quedó ilegible sobre el naranja. Mismo
   esquema que el estado "scrolled" (que si acierta el contraste): crema
   translúcido de base, blanco sólido en hover, dorado para la página activa
   y para la barrita que se llena — consistente con el logo de al lado. */
body.home .site-header .main-nav a{ color:rgba(247,251,240,.82); transition:color .35s var(--ease); }
body.home .site-header .main-nav a:hover{ color:var(--cream); }
body.home .site-header .main-nav a[aria-current="page"]{ color:var(--gold-light); }
body.home .site-header .main-nav a::after{ background:var(--gold-light); }
body.home .site-header .btn-ghost{ border-color:var(--cream); color:var(--cream); transition:color .35s var(--ease), border-color .35s var(--ease), background .25s; }
body.home .site-header .btn-ghost:hover{ background:var(--cream); color:var(--espresso); border-color:var(--cream); }
body.home .site-header .nav-toggle{ border-color:var(--espresso); color:var(--espresso); }

body.home .site-header.scrolled{ box-shadow:0 10px 30px rgba(6,21,15,.25); }
body.home .site-header.scrolled::before{ clip-path:inset(0 0 0% 0); }
body.home .site-header.scrolled .brand-word{ color:var(--cream); }
body.home .site-header.scrolled .brand-mark{ filter:none; }
body.home .site-header.scrolled .main-nav a{ color:rgba(247,251,240,.82); }
body.home .site-header.scrolled .main-nav a:hover{ color:var(--cream); }
body.home .site-header.scrolled .main-nav a[aria-current="page"]{ color:var(--gold-light); }
body.home .site-header.scrolled .main-nav a::after{ background:var(--gold-light); }
body.home .site-header.scrolled .btn-ghost{ border-color:rgba(247,251,240,.4); color:var(--cream); }
body.home .site-header.scrolled .btn-ghost:hover{ background:var(--cream); color:var(--espresso); border-color:var(--cream); }
body.home .site-header.scrolled .nav-toggle{ border-color:rgba(247,251,240,.4); color:var(--cream); }

/* ---- Páginas interiores: mismo barrido a oscuro al hacer scroll, no solo en
   home. Antes esto vivía SOLO dentro de `body.home .site-header.scrolled` —
   en las páginas interiores el header se quedaba en su versión clara (crema,
   texto oscuro) sin importar cuánto se hiciera scroll. Este bloque genérico
   (sin `body.home`) repite exactamente los mismos cambios — mismo barrido
   (::before), mismos colores crema en el texto — pero aplica en CUALQUIER
   página. En home no pasa nada distinto: las reglas de arriba (con
   `body.home`, más específicas) siguen ganando ahí, así que esto solo le
   suma el efecto a las páginas que no lo tenían. */
.site-header.scrolled::before{ clip-path:inset(0 0 0% 0); }
.site-header.scrolled .brand-word{ color:var(--cream); }
.site-header.scrolled .main-nav a{ color:rgba(247,251,240,.82); }
.site-header.scrolled .main-nav a:hover{ color:var(--cream); }
.site-header.scrolled .main-nav a[aria-current="page"]{ color:var(--gold-light); }
.site-header.scrolled .main-nav a::after{ background:var(--gold-light); }
.site-header.scrolled .btn-ghost{ border-color:rgba(247,251,240,.4); color:var(--cream); }
.site-header.scrolled .btn-ghost:hover{ background:var(--cream); color:var(--espresso); border-color:var(--cream); }
.site-header.scrolled .nav-toggle{ border-color:rgba(247,251,240,.4); color:var(--cream); }

body.home .hero{ padding-top:82px; }

.brand{ display:flex; align-items:center; gap:11px; }
.brand-mark{ width:46px; height:31px; flex:0 0 auto; }
.brand-word{ font-family:var(--display); font-weight:800; font-size:21.5px; letter-spacing:-.01em; color:var(--espresso); }

.main-nav{ display:flex; align-items:center; gap:2px; }
.main-nav a{
  display:block;
  font-size:clamp(12.5px,1.35vw,16px); font-weight:700; letter-spacing:.01em; color:var(--espresso-soft);
  padding:10px clamp(8px,1.1vw,16px); border-radius:4px; position:relative; transition:color .25s;
}
.main-nav a::after{
  content:""; position:absolute; left:14px; right:14px; bottom:5px; height:2px;
  background:var(--terracotta); transform:scaleX(0); transform-origin:left; transition:transform .3s var(--ease);
}
.main-nav a:hover{ color:var(--espresso); }
.main-nav a:hover::after{ transform:scaleX(1); }
/* Página activa: el link de la sección en la que estás queda marcado con el
   mismo subrayado que el hover, pero fijo (no necesita pasar el mouse), y en
   terracota para que se distinga de los demás. Vale para las 3 variantes de
   color del header (normal, home transparente, home scrolled) y para el
   menú de mobile más abajo. */
.main-nav a[aria-current="page"]{ color:var(--terracotta-dark); }
.main-nav a[aria-current="page"]::after{ transform:scaleX(1); }

/* ---- Mega menú — de regreso a tarjeta clara flotante (la barra oscura de ancho
   completo no convenció), columnas de solo texto plano: un pequeño encabezado de
   categoría por columna + enlaces, sin iconos ni tarjetas internas. */
.nav-item{ position:relative; }
/* El menú se abre/cierra por :hover en .nav-item, y como .mega-menu es su
   descendiente, hover encima de CUALQUIER parte de .mega-menu también cuenta
   como hover en .nav-item — en teoría no debería poder "perderse" al bajar el
   mouse. El problema real era el `margin-top:14px` de antes: eso deja un
   colchón de 14px de página VACÍA entre el link y la tarjeta que no es
   territorio de ningún elemento (ni el link, que termina arriba, ni la
   tarjeta, que empieza más abajo) — el mouse cruza por ahí, sale de .nav-item
   sin haber entrado todavía a .mega-menu, y el navegador cierra el menú antes
   de que el cursor llegue a los enlaces. Solución: .mega-menu (el que abre y
   cierra) va PEGADO al link (top:100%, sin margen) para que no haya hueco sin
   cubrir; el espacio de aire visual se mueve a un padding-top DENTRO de
   .mega-menu — sigue viéndose igual de separado, pero ahora ese aire también
   es parte de la caja hoverable. La tarjeta blanca (fondo, sombra, columnas)
   vive en .mega-menu-inner. */
/* --mega-shift (0px por defecto): corrección horizontal calculada en JS
   (main.js) para que el menú no se corte contra el borde del viewport en
   anchos angostos de escritorio — .nav-item de Proveedores/Alianzas quedan
   cerca del borde izquierdo, y centrado a ciegas bajo el link a veces se
   salía de la pantalla. Sin JS (o si no hace falta corregir) --mega-shift
   vale 0 y el menú se ve exactamente igual que antes. */
.mega-menu{
  position:absolute; top:100%; left:50%; transform:translate(calc(-50% + var(--mega-shift, 0px)),8px);
  width:min(640px,90vw); padding-top:14px;
  opacity:0; pointer-events:none; transition:opacity .12s ease, transform .18s ease;
}
.nav-item:hover .mega-menu, .nav-item:focus-within .mega-menu{
  opacity:1; pointer-events:auto; transform:translate(calc(-50% + var(--mega-shift, 0px)),0);
}
.mega-menu-inner{
  padding:34px 36px;
  background:var(--white); border-radius:var(--radius); box-shadow:0 24px 48px rgba(11,43,32,.18);
  display:flex; gap:28px;
}
/* min-width:0 es la parte que faltaba: un hijo flex por default NO se encoge
   más allá del ancho de su contenido (min-width:auto), así que una palabra
   larga sin espacios ("proveedores", "documentación") empujaba la columna
   entera fuera del recuadro blanco en vez de partirse en dos líneas — eso
   es lo que se veía como letras "sin fondo blanco atrás". overflow-wrap
   es el respaldo por si una palabra sigue sin caber ni partiéndose por
   espacio. */
.mega-col{ flex:1; min-width:0; padding:0 18px; border-left:1px solid var(--line); overflow-wrap:break-word; }
.mega-col:first-child{ padding-left:0; border-left:0; }
.mega-col h6{
  font-size:12.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--terracotta-dark); margin-bottom:14px;
}
/* Esta regla base vivía SOLO dentro de `body.home` (ver el bloque de abajo),
   así que en cualquier página que no fuera el home, `.mega-col a` nunca la
   recibía y cascadeaba hasta `.main-nav a` (16px, bold 700, padding:10px 16px
   — pensado para los links horizontales del nav, no para una lista vertical
   angosta). Ese texto más grande y con más padding es justo lo que hacía que
   palabras largas ("homologación", "proveedores") no cupieran en la columna y
   se salieran del recuadro blanco. Puesta aquí, sin `body.home`, aplica en
   todas las páginas — y ya gana por especificidad (dos clases) sobre
   `.main-nav a` (una clase) sin necesitar el prefijo. */
/* width:fit-content (en vez de ancho completo de columna) es la pieza clave:
   sigue siendo `display:block` así que cada link ocupa su propia fila (se
   siguen apilando, no se van de lado), pero la CAJA del link ahora mide
   exactamente lo que mide su texto — ya no el ancho completo de la columna.
   Eso es lo que permite que el ::after (la misma barrita que se "llena" del
   nav principal, no el subrayado nativo del navegador) calce con el texto
   real en vez de estirarse hasta el borde de la columna o subrayar cada
   línea suelta de un texto envuelto en dos renglones. */
.mega-col a{
  display:block; width:fit-content; max-width:100%; position:relative;
  font-size:14.5px; font-weight:600; color:var(--ink); padding:7px 0;
  transition:color .2s;
}
.mega-col a::after{
  content:""; position:absolute; left:0; right:0; bottom:2px; height:2px;
  background:var(--terracotta); transform:scaleX(0); transform-origin:left;
  transition:transform .3s var(--ease);
}
.mega-col a:hover{ color:var(--terracotta); }
.mega-col a:hover::after{ transform:scaleX(1); }
/* Especificidad reforzada con !important: el menú vive DENTRO de .main-nav,
   y hay varias reglas de color para .main-nav a (home transparente, home
   scrolled, interior scrolled, cada una con su propio prefijo "body.home"
   o no) — cada una compitiendo por especificidad con esta. Ya hubo dos
   rondas de bugs por esto: primero perdía siempre contra la home (letras
   invisibles ahí), después, al quitarle el prefijo "body.home" para que
   aplicara en todas las páginas, perdió el empate de especificidad contra
   la regla general de header oscuro en páginas interiores (mismo número de
   clases, pero esa regla tiene además el elemento "body" delante, que
   desempata a su favor). En vez de seguir sumando clases para ganar la
   carrera, !important corta el problema de raíz: el mega menú SIEMPRE cae
   sobre fondo blanco (.mega-menu-inner), así que su texto nunca debe
   heredar el color del nav del header, sea cual sea su estado. */
.site-header .main-nav .mega-col a,
.site-header.scrolled .main-nav .mega-col a{ color:var(--ink) !important; }
.site-header .main-nav .mega-col a:hover{ color:var(--terracotta) !important; }
.site-header.scrolled .main-nav .mega-col a:hover{ color:var(--gold-light) !important; }
.site-header.scrolled .main-nav .mega-col a:hover::after{ background:var(--gold-light); }

.header-right{ display:flex; align-items:center; gap:clamp(10px,1.2vw,18px); }
/* El CTA del header ("Contáctanos"/"Fale conosco") comparte fila con el logo
   y los 7 links del menú — a un tamaño fijo (heredado de .btn, 16.5px +
   padding:11px 20px) era el elemento más ancho sin ceder nada, empujando al
   resto a apretarse en pantallas angostas de escritorio (861-1100px aprox).
   Responsivo con el mismo criterio que el resto del header. */
.header-right .btn-ghost{ font-size:clamp(12.5px,1.35vw,16.5px); padding:clamp(8px,1.2vw,11px) clamp(12px,2vw,20px); }

.btn{
  display:inline-flex; align-items:center; gap:9px; white-space:nowrap;
  font-size:16.5px; font-weight:800; letter-spacing:.01em;
  padding:17px 30px; border-radius:0; border:1px solid transparent;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease), background .25s, border-color .25s, color .25s, border-radius .25s var(--ease);
}
/* En reposo, geométrico (esquina recta) — al seleccionar/hover, un toque muy
   ligero de la silueta de marca (una esquina se curva un poco), nada más. */
.btn:hover, .btn:focus-visible{ border-radius:0 16px 0 0; }
.btn svg{ width:14px; height:14px; transition:transform .25s var(--ease); }
.btn:hover svg{ transform:translateX(3px); }
.btn-dark{ background:var(--espresso); color:var(--cream); }
.btn-dark:hover{ background:var(--terracotta); transform:translateY(-2px); box-shadow:0 12px 24px rgba(221,78,12,.3); }
.btn-pill{ background:var(--cream); color:var(--espresso); }
.btn-pill:hover{ background:var(--espresso); color:var(--cream); transform:translateY(-2px); }
.btn-text{ padding:13px 4px; color:var(--espresso); font-weight:800; }
.btn-text:hover{ color:var(--terracotta); }
.btn-text:hover svg{ transform:translateX(3px); }
.btn-ghost{ border-color:var(--line-strong); color:var(--espresso); padding:11px 20px; }
.btn-ghost:hover{ border-color:var(--espresso); background:var(--espresso); color:var(--cream); }

.nav-toggle{ display:none; align-items:center; justify-content:center; width:38px; height:38px; border:1px solid var(--line-strong); border-radius:4px; }
.nav-toggle svg{ width:16px; height:16px; }
/* Solo existe para el menú de mobile/tableta (ver media query) — oculto por
   default para que en escritorio no aparezca como un bloque suelto dentro
   del nav. */
.mobile-nav-extra{ display:none; }

/* ============ HERO (composición tipo Olam: bloque de color + foto en diagonal) ============ */
/* "Pinned hero": el hero se queda FIJO en el viewport (position:fixed) y el resto
   del contenido (.page-content) sube por encima al hacer scroll, tapándolo poco a
   poco — y al subir de vuelta, se destapa. .hero-spacer reserva el espacio que el
   hero dejó de ocupar en el flujo normal al volverse fixed. Solo en desktop: en
   mobile el hero vuelve a comportarse normal (ver media query abajo). */
/* Fondo terracota (no oro) — es el tono de tu marca con luminosidad real de "naranja",
   por eso aguanta texto blanco encima, igual que Olam sobre su naranja.
   align-items:flex-start (no "center"): con "center", en pantallas de poca
   altura (o con el mensaje más largo de los 3, que ocupa más renglones) el
   bloque de texto se centraba verticalmente en el 100vh completo, y ese
   centrado podía llegar a empujar el título POR ENCIMA del header — se
   veía pegado/encimado con la barra de navegación. Con flex-start, la
   posición del texto la controla solo el padding-top de .hero-inner (fijo,
   pensado para el header más alto posible), así el título siempre arranca en
   el mismo punto seguro sin importar la altura de pantalla ni cuántos
   renglones tenga cada mensaje. */
.hero{
  position:fixed; top:0; left:0; right:0; z-index:0;
  height:100vh; min-height:560px; display:flex; align-items:flex-start;
  background:var(--terracotta); overflow:hidden; color:var(--cream);
}
.hero-spacer{ height:100vh; min-height:560px; }
.page-content{ position:relative; z-index:1; background:var(--cream); }
/* Curva real tipo "S", calcada de tu boceto (plana arriba, cae fuerte en medio,
   plana abajo) — un solo border-radius circular NUNCA puede lograr esa forma
   (una elipse gigante siempre sigue curveando, nunca se aplana). Se necesita un
   clip-path con una curva bézier real: el <clipPath> con el path está al final
   del <body> del HTML (objectBoundingBox, así escala con el tamaño de la caja).
   El área que queda VISIBLE (foto) es todo lo que está a la izquierda/abajo de
   esa curva — arriba del todo casi no se ve foto, se va abriendo hacia abajo. */
/* top fijo en 134px (el alto del header EXPANDIDO, con la barra de utilidad
   arriba) a propósito, ya no usa --header-h. Antes usaba esa variable, que
   main.js actualiza en vivo cuando el usuario hace scroll (134px -> 82px al
   comprimirse el header) — eso hacía que la foto (y el título, ver
   .hero-inner) se movieran/reacomodaran en el momento exacto en que el header
   se comprime, un "salto" visible confirmado con video real comparando contra
   el sitio de referencia (Olam: ahí el header se comprime SOLO, sin mover el
   Hero de abajo para nada). El header ya va encima con position:fixed y más
   z-index, así que no hace falta que el Hero reaccione a su alto — con top
   fijo en el alto MÁXIMO del header, nunca hay traslape (el caso ya cubierto
   antes) y el Hero se queda perfectamente quieto sin importar si el header
   está expandido o comprimido. */
/* Ya NO tiene clip-path aquí (ver .hero-photo-mask más abajo para el porqué):
   .hero-photo ahora es un rectángulo normal sin recortar, la curva se pinta
   con una forma sólida ENCIMA en vez de recortar la foto por debajo. */
.hero-photo{
  position:absolute; z-index:0;
  left:0; right:0; top:134px; bottom:0;
}
/* Corregido con evidencia de video real, esta vez viendo el momento exacto de la
   transición cuadro a cuadro: NO es fundido (nunca hay dos fotos translúcidas
   encimadas) y NO es deslizamiento de carrete. Es un WIPE opaco — la foto nueva
   entra cubriendo a la vieja desde un lado (izquierda en unos mensajes, derecha
   en otros), con un borde limpio que barre hasta cubrir el 100%. Las fotos se
   apilan todas en el mismo sitio; la que "entra" sube de z-index y se revela con
   un barrido animado; las demás se quedan abiertas y opacas debajo, sin animar.
   Antes esto se hacía con clip-path (inset animado), y antes de eso con
   translateX (transform). Ambas veces medí con getComputedStyle en el navegador
   de pruebas y SÍ interpolaba bien cuadro a cuadro — pero en video real de la
   usuaria, en su equipo, seguía viéndose como un corte instantáneo con las dos
   versiones. La causa real: .hero-photo-slide vive ANIDADO dentro de
   .hero-photo, que tenía su propio clip-path:url(#heroCurve) (un <clipPath>
   SVG). Chromium no acelera por GPU ese tipo de clip-path, y ESO también le
   quita la aceleración a cualquier transform animado en sus hijos — no importa
   qué propiedad se anime por dentro, mientras el padre recorte con un SVG
   clip-path, todo el subárbol se pinta por software en cada cuadro. La única
   forma real de arreglarlo es sacar el clip-path del padre por completo (ver
   .hero-photo-mask): así .hero-photo-slide ya no tiene ningún ancestro
   recortado y el navegador sí puede darle su propia capa acelerada. */
.hero-photo-track{ position:absolute; inset:0; overflow:hidden; }
.hero-photo-slide{
  position:absolute; inset:0; overflow:hidden; z-index:0;
  transform:translateX(-100%);
  transition:transform 1.15s cubic-bezier(.65,0,.35,1);
}
.hero-photo-slide.alt{ transform:translateX(100%); }
.hero-photo-slide.active{ transform:translateX(0); }
.hero-photo-track img{
  width:100%; height:100%; object-fit:cover;
  animation:kenburns 24s ease-in-out infinite alternate;
}
@keyframes kenburns{ from{ transform:scale(1); } to{ transform:scale(1.06) translate(-1%,-.6%); } }
/* Matiz leve en una esquina — la foto se queda brillante, a la par del color de fondo. */
.hero-photo::after{
  content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(200deg, rgba(11,43,32,.16), rgba(11,43,32,0) 45%);
}

/* Capa de primer plano — placeholder. Aquí es donde van tus fotos recortadas (sujeto sin
   fondo, PNG con transparencia). Crossfade puro, sincronizado con la foto de fondo —
   sin ningún elemento aparte cruzando la pantalla (confirmado: Olam no usa eso). */
.hero-fg{
  position:absolute; inset:0; z-index:2; pointer-events:none; opacity:0;
  background:linear-gradient(0deg, rgba(6,21,15,.18), rgba(6,21,15,0) 30%);
  transition:opacity 1.4s ease;
}
.hero-fg.active{ opacity:1; }

/* Pinta la curva como forma SÓLIDA encima de la foto, en vez de recortar la
   foto por debajo con clip-path (ver nota larga en .hero-photo-track sobre por
   qué eso rompía la animación del barrido). Es la silueta INVERSA de la curva
   original (el lado naranja/fondo, no el lado de la foto), del mismo color de
   fondo del Hero — visualmente es IDÉNTICA al recorte de antes (mismo path,
   solo que relleno en vez de usado como máscara), pero como es una forma
   estática que nunca cambia, el navegador la pinta una sola vez; no vuelve a
   tocarla en cada cuadro de la animación de las fotos de abajo.
   width/height:100% explícitos, a propósito: con solo inset:0, un <svg> se
   comporta como "elemento reemplazado" y algunos navegadores lo dimensionan
   según su PROPIA relación de aspecto intrínseca (la del viewBox, "0 0 1 1" =
   cuadrada) en vez de estirarse al rectángulo real de .hero-photo — así se
   veía la curva "aplanada" (evidencia real: medí el <svg> ya renderizado y
   medía 1384×1384, cuadrado, en vez de 1384×666, el tamaño real de la foto).
   width/height:100% fuerza el tamaño real sin dejarle margen a esa regla.
   z-index:50 (antes 3) por otro bug real, evidencia otra vez de video/captura:
   cada vez que entra una foto nueva, main.js le sube su propio z-index
   (variable zTop, ++zTop en cada cambio) y ESE NÚMERO NUNCA SE REINICIA —
   sigue subiendo para siempre mientras el carrusel avanza. Con la máscara en
   z-index:3, bastaban 3-4 cambios de foto para que zTop superara ese 3 y la
   foto quedara POR ENCIMA de la máscara — ahí es cuando "se hace el
   recuadro": la foto se ve completa, rectangular, sin la curva ni el fondo
   naranja. 50 es un techo cómodo que zTop no va a alcanzar en una sesión
   normal de navegación. */
.hero-photo-mask{ position:absolute; inset:0; width:100%; height:100%; z-index:50; pointer-events:none; }
.hero-photo-mask path{ fill:var(--terracotta); }

/* Solo padding vertical aquí a propósito: el horizontal lo hereda de
   .container (esta caja también tiene esa clase) — así el texto respeta el
   mismo margen contra el borde que el resto del sitio, y sigue el mismo
   ajuste responsive de .container en cada breakpoint sin duplicarlo aquí.
   padding-top fijo en 134px (alto del header EXPANDIDO) + 26px de aire — así
   el título nunca arranca más arriba de lo que el header ocupa, sin importar
   la altura de pantalla. Ya NO usa var(--header-h): esa variable cambia en
   vivo con el scroll (main.js la baja a 82px cuando el header se comprime), y
   atar el padding-top del Hero a eso hacía que el título se reacomodara justo
   cuando el header se comprime — se ve como si "todo el Hero se moviera" al
   hacer scroll (confirmado con video real comparando contra el sitio de
   referencia, donde el header se comprime solo sin mover nada del Hero). Con
   un valor fijo basado en el header MÁS ALTO posible, sobra espacio de sobra
   cuando el header se comprime (nunca falta, nunca hay traslape) y el Hero ya
   no se mueve nunca por el scroll. El aire extra sobre esos 134px bajó de
   56px a 26px en un ajuste previo (empujaba los botones fuera de la primera
   vista) y ahora otra vez, a -4px (130px en total): se pidió subir un poco
   más todo el bloque (título + párrafo + botones). Sigue habiendo margen
   claro contra el header, ya que 134px es el alto REAL del header expandido,
   no aire extra. */
.hero-inner{ position:relative; z-index:4; width:100%; padding-top:130px; padding-bottom:48px; }
/* Espejo completo: el texto no solo se empuja a la derecha como bloque — se alinea
   a la derecha de verdad (texto, párrafo y botones), como pediste. */
/* grid-template-columns:minmax(0,1fr) es la causa real detrás de que el
   texto se saliera por la derecha en mobile: sin especificarla, la columna
   implícita de un grid se dimensiona por CONTENIDO (el texto más ancho que
   tenga cualquiera de los 3 mensajes), no por el espacio disponible — en
   escritorio nunca se notaba porque max-width:960px daba de sobra, pero en
   mobile (que quita ese límite) esa columna podía terminar más ancha que la
   pantalla, y el texto se salía por el borde derecho. minmax(0,1fr) obliga a
   la columna a respetar el ancho real del contenedor. */
/* max-width bajó de 960px a min(860px, 52vw): con 960px fijo y el título
   grande, el mensaje más largo ("Su producto puede llegar más lejos con el
   socio adecuado.") envolvía a 3 líneas donde la última quedaba tan ancha que
   su borde izquierdo caía sobre la curva de la foto (evidencia: video real,
   se veía el texto "el" literalmente encima de la grúa del puerto). Un valor
   fijo en px no alcanza: la curva (heroCurve, ver <clipPath> en el HTML) llega
   hasta el 58% del ancho de la ventana cerca de la parte baja de la foto —
   es una FRACCIÓN del viewport, no píxeles fijos — así que en pantallas más
   angostas (~900px) 860px de columna de texto SÍ se mete en la curva aunque
   en pantallas anchas (1920px) sobrara de margen (confirmado midiendo la
   posición real de cada línea contra la curva en varios anchos: con solo
   860px fijo daba overlap negativo en 900px de ancho). min(860px, 52vw) ata
   el límite también a una fracción del viewport, así que el margen contra la
   curva se mantiene positivo sin importar el ancho de pantalla. */
/* Vuelto a min(860px,52vw) — bajarlo a 700px angostaba tanto la columna que
   el mensaje más largo (portugués) envolvía a 4 líneas en vez de 3, y ESO
   fue lo que de verdad empujaba los botones y los puntos fuera de pantalla
   en laptop, no el ancho en sí. La corrección real está en el tamaño de
   letra de abajo (clamp con vw Y vh): con el título más chico en pantallas
   angostas/bajas, el mensaje más largo vuelve a caber en 2-3 líneas con el
   ancho original, y ya no hace falta angostar la columna. */
/* Se probó subir esto a min(960px,57vw) a pedido del cliente (menos líneas
   forzadas) pero medido contra la curva real (heroCurve) con el mensaje más
   largo (portugués, "Seu parceiro operacional...") el margen se vuelve
   NEGATIVO a partir de ~54vw — el texto invade la foto, el mismo bug que ya
   costó varias rondas arreglar. Se queda en 52vw (el valor seguro,
   verificado con margen positivo en todos los anchos probados). */
/* text-align pasó de right a left (mismo cambio que el Hero de páginas
   interiores, mismo motivo: líneas de distinto largo alineadas a la derecha
   se veían "dentadas" del lado izquierdo, y el botón lo acentuaba). El
   bloque se queda en el mismo lugar (max-width/margin-left:auto sin
   cambios — el margen de seguridad contra la curva no depende de hacia
   qué lado fluye el texto adentro de esa misma columna). */
.hero-slide-wrap{ display:grid; grid-template-columns:minmax(0,1fr); max-width:min(860px, 52vw); margin-left:auto; text-align:right; }
/* Texto y botones se mueven como UN solo bloque (confirmado en Olam): al salir, se
   desvanecen y suben un poco; el que entra, sube desde abajo mientras aparece — nunca
   los dos a la vez (primero sale, después entra), y los botones van pegados al texto. */
.hero-slide{
  grid-area:1/1; display:flex; flex-direction:column; align-items:flex-end;
  opacity:0; transform:translateY(22px); pointer-events:none; z-index:1;
  transition:opacity .5s ease, transform .5s ease;
}
.hero-slide.active{ opacity:1; transform:translateY(0); pointer-events:auto; z-index:3; }
.hero-slide.leaving{ opacity:0; transform:translateY(-22px); transition:opacity .4s ease, transform .4s ease; z-index:2; }
/* Bajó de clamp(41px,7vw,101px): con 101px el mensaje más largo envolvía a 3
   líneas tan altas que empujaba los botones fuera de la primera vista y, ya
   que la última línea quedaba muy ancha, invadía la curva de la foto (ver
   nota en .hero-slide-wrap). No es un cambio drástico — sigue siendo un
   título grande — pero libera suficiente alto y ancho para resolver ambos
   problemas sin tener que achicarlo mucho más. */
.hero h1{
  font-size:calc(clamp(34px,5vw,84px) * var(--hero-fit,1)); line-height:1.02; margin:0 0 26px; color:var(--cream); font-weight:800;
}
/* Antes .accent-word iba en --espresso (casi negro) sobre el fondo naranja
   del Hero — observación del reporte: el texto "destacado" se leía con
   MENOS peso que el resto (blanco), justo al revés de lo que un acento
   debería hacer. Un tono oscuro se hunde en un fondo de color; el dorado
   de marca salta hacia adelante — ahora si se nota como el énfasis. */
.hero h1 .accent-word{ color:var(--gold); }
.hero p{ max-width:46ch; font-size:19.5px; color:rgba(247,251,240,.86); margin-bottom:0; font-weight:500; margin-left:auto; }
/* Los botones van pegados al párrafo (no anclados hasta el fondo del hero): el espacio
   que dejan depende del texto de cada mensaje, no de la altura total de la sección. Se
   mueven junto con el título y el párrafo como un solo bloque (.hero-slide), no aparte.
   justify-content:flex-end — de vuelta a la derecha en escritorio, ver nota
   de más arriba: solo la versión apilada real (sin curva) queda a la
   izquierda, no el escritorio ni el rango con curva. */
/* --btn-guard-shift (0px por defecto, calculado en main.js): el título y el
   párrafo de arriba SÍ pueden usar el ancho completo de la columna sin
   problema (el texto nunca toca la curva — tiene aire alrededor de las
   letras), pero el botón es una caja sólida y su borde recto SÍ se puede
   ver rozar la curva, sobre todo cuando el título envuelve a pocas líneas y
   deja los botones más abajo, donde la curva es más ancha. En vez de
   adivinar un número de píxeles fijo (frágil: cambia con el ancho de
   pantalla, el idioma y qué tan largo sea cada mensaje del carrusel),
   main.js mide en tiempo real dónde cae realmente el borde de la curva a
   la altura de los botones y angosta SOLO esta fila lo justo para que
   quede despejada — título y párrafo no se tocan. */
.hero-actions{
  display:flex; align-items:center; justify-content:flex-end;
  gap:clamp(8px,1vw,14px); flex-wrap:wrap; margin-top:0; padding-top:34px;
  width:100%; max-width:calc(100% - var(--btn-guard-shift, 0px)); transform:translateZ(0);
}
/* SOLO el botón se vuelve responsivo (letra y relleno en clamp con vw) — el
   título y el párrafo se quedan fijos como estaban, a pedido explícito: el
   problema real es que el botón no se achicaba nunca, así que en pantallas
   de laptop (angostas) los dos botones juntos no cabían en una fila y el
   segundo se salía del área segura. clamp() con vw hace que a partir de
   cierto ancho el botón empiece a encogerse solo; flex-wrap (arriba) ya
   manda el 2° botón a su propia fila cuando de plano no caben los dos —
   con el botón más chico esa 2ª fila también ocupa menos alto. Arriba de
   ~1270px de ancho el botón se queda en su tamaño de siempre (16.5px/17·30). */
.hero-actions .btn{
  font-size:clamp(13px,.95vw,16.5px); padding:clamp(7px,.9vw,17px) clamp(10px,1.6vw,30px);
}
.hero .btn-text{ color:var(--cream); }
.hero .btn-text:hover{ color:var(--espresso); }

/* transform:translateZ(0) fuerza su propia capa de composición — sin esto,
   cada transición del carrusel fuerza un reflow de TODA la página (ver
   fg.offsetWidth en main.js) y en algunos equipos/navegadores eso hace que
   el navegador "olvide" repintar estos puntos justo ese cuadro, aunque su
   posición calculada (verificada en vivo) siempre es correcta — es un
   parche de pintura, no de posición. */
.hero-dots{ display:flex; gap:clamp(6px,.7vw,10px); margin-top:44px; margin-left:auto; width:fit-content; position:relative; z-index:4; transform:translateZ(0); }
.hero-dots button{ width:34px; height:3px; background:rgba(247,251,240,.35); border-radius:2px; transition:background .3s, width .3s; }
.hero-dots button.active{ background:var(--cream); width:52px; }

/* ============ TRES PUERTAS ============ */
.doors{ padding:clamp(40px,3.4vw,60px) 0; }
.section-head{ max-width:680px; margin-bottom:clamp(32px,2.78vw,50px); }
/* Coeficiente vw bajado de 3.6 a 2.44: con 3.6 el título llegaba a su tamaño
   MÁXIMO (44px) a partir de apenas 1222px de ancho — es decir, en la
   inmensa mayoría de laptops/monitores normales (1280–1920px) se veía
   siempre al tope, sin ninguna gradación real. Con 2.44vw el techo se
   alcanza hasta 1800px — mismo criterio ya usado en el botón del Hero y la
   barra de navegación. El piso (30px) no cambia, así que en pantallas
   angostas se comporta exactamente igual que antes. */
.section-head h2{ font-size:clamp(30px,2.44vw,44px); margin-top:14px; line-height:1.1; }
.section-head p{ color:var(--ink-soft); font-size:18.1px; margin-top:14px; max-width:54ch; font-weight:500; }
/* Reportado: "Identifique su recorrido y avance..." se veía partida en 2
   líneas sin necesidad — el límite de .section-head (680px/54ch) es
   compartido por TODAS las secciones del sitio que usan esta clase, así que
   en vez de ensancharlo globalmente (podría afectar otras secciones donde
   680px sí es el ancho correcto), se amplía solo para esta sección
   (#puertas) — no hay foto/curva cerca de este bloque, así que no hay
   riesgo de invadir nada, solo cabe la frase completa en una línea en
   pantallas de escritorio normales. */
#puertas .section-head{ max-width:960px; }
#puertas .section-head p{ max-width:none; }

/* flex + wrap en vez de grid: reportado que cuando sobra 1 tarjeta en la
   última fila (ej. 3 tarjetas en 2 columnas) quedaba pegada a la izquierda
   con un hueco enorme a la derecha — justify-content:center resuelve
   cualquier cantidad de sobrantes, sin importar cuántas columnas quepan,
   mismo truco que ya se usó en .stats-grid. */
.doors-grid{ display:flex; flex-wrap:wrap; justify-content:center; gap:clamp(16px,1.22vw,22px); }
.door{ flex:1 1 320px; max-width:460px; }

/* Puertas — de regreso a foto real (pediste que fuera con imágenes, tipo la
   tarjeta de noticias de Olam): foto arriba con la esquina curva, contenido en
   fondo claro ABAJO (no overlay encima de la foto). Hover: se levanta, la foto
   hace un zoom lento — misma coreografía de siempre. */
/* La curva vive en TODA la tarjeta (no solo en la foto): antes .door-photo
   tenía su propio border-radius mientras .door (el fondo blanco de atrás) se
   quedaba en escuadra — al crecer la curva en hover, esa esquina dejaba ver
   el rectángulo blanco de .door justo detrás, como un "cuadro" suelto. Con
   un solo border-radius en la tarjeta completa, la curva recorta la foto Y
   la tarjeta a la vez: no hay una segunda caja blanca escondida detrás. */
.door{
  background:var(--white); overflow:hidden;
  --corner:52px; border-radius:0 var(--corner) 0 0;
  display:flex; flex-direction:column;
  transition:transform .35s var(--ease), box-shadow .35s var(--ease), border-radius .4s var(--ease);
}
.door:hover{ --corner:88px; transform:translateY(-8px); box-shadow:0 26px 48px rgba(11,43,32,.18); }
.door-photo{ aspect-ratio:4/3; overflow:hidden; }
.door-photo img{ width:100%; height:100%; object-fit:cover; transition:transform .9s var(--ease); }
.door:hover .door-photo img{ transform:scale(1.07); }
.door-content{ padding:26px 28px 30px; }
.door-tag{ font-size:14.4px; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--door-tag,var(--terracotta-dark)); }
.door h3{ font-size:19px; margin:12px 0 8px; font-weight:800; line-height:1.25; color:var(--espresso); }
.door p.support{ font-size:18.1px; margin-bottom:18px; font-weight:500; color:var(--ink-soft); }
.door .btn-text{ padding-left:0; color:var(--espresso); }
.door .btn-text:hover{ color:var(--door-tag,var(--terracotta-dark)); }

.door--proveedores{ --door-tag:var(--gold); }
.door--aliados{ --door-tag:var(--terracotta); }
.door--inversores{ --door-tag:var(--espresso-soft); }

/* ============ CATEGORÍAS DE PRODUCTO (tarjeta oscura, referencia Olam Agri) ============
   Fondo espresso sólido, título + texto de apoyo arriba, ícono circular de línea
   abajo. La curva de marca ahora aparece arriba-derecha Y abajo-izquierda (no solo
   una esquina) para que se sienta más presente en la tarjeta, no escondida. */
/* auto-fit en vez de un número fijo de columnas: así esta grid sirve tanto para
   3 tarjetas (categorías de producto) como para 5 (motivos) u otra cantidad en
   futuras páginas, sin dejar huecos raros en la última fila. */
/* flex + wrap en vez de grid con auto-fit: con grid, cualquier fila
   incompleta (ej. la 5ª tarjeta de Proveedores sola, o la 3ª/4ª de
   Empresa/Logística/Oportunidades en 2 columnas) quedaba pegada a la
   izquierda con un hueco enorme a la derecha — antes esto se resolvía con
   un caso especial solo para "exactamente 5 tarjetas" (nth-child), pero el
   mismo problema aparecía con cualquier otra cantidad. justify-content:
   center centra la fila sobrante sola, sin importar cuántas tarjetas
   sobren ni en qué página. */
.cats-grid{ display:flex; flex-wrap:wrap; justify-content:center; gap:clamp(14px,1.11vw,20px); }
.cat-card{ flex:1 1 240px; max-width:320px; }
/* Tarjeta "skew card": réplica directa del componente de referencia (panel
   de color sesgado detrás, que se endereza y se expande en hover, con el
   texto sobre un panel de vidrio esmerilado) — sin íconos/stickers, solo
   título + texto sobre el panel de color, como en el video. */
.cat-card{
  position:relative; overflow:hidden; isolation:isolate;
  background:#0A1F17; color:var(--cream);
  /* clamp en vez de 380px fijo: con auto-fit ya resolviendo cuántas
     columnas caben, una tarjeta angosta (3 columnas) sigue queriendo el
     mismo alto que una tarjeta a ancho completo (1 columna) — con fijo,
     esta última quedaba con muchísimo aire vacío debajo del texto. Con
     clamp() ligado a vw, el alto se relaciona con el ancho real de
     pantalla en vez de ser el mismo número siempre. */
  min-height:clamp(220px,22vw,380px); padding:28px 26px;
  display:flex; align-items:flex-start;
  --corner:52px; border-radius:0 var(--corner) 0 0;
  transition:transform .4s var(--ease), box-shadow .4s var(--ease), border-radius .4s var(--ease);
}
/* Resplandor de color alrededor de toda la tarjeta en hover (box-shadow no
   se recorta por el overflow:hidden de la tarjeta) — esto es lo que le da
   el aspecto "neón" de la referencia sin tener que quitarle el recorte
   limpio a la tarjeta. */
.cat-card:hover{
  --corner:88px; transform:translateY(-8px);
  box-shadow:0 26px 48px rgba(11,43,32,.3), 0 0 70px -10px var(--cat-color, var(--gold-light));
}
.cat-card::before, .cat-card::after{
  content:""; position:absolute; top:0; left:32px; right:24px; height:100%;
  border-radius:16px;
  background:linear-gradient(325deg, color-mix(in srgb, var(--cat-color, var(--gold-light)) 75%, white), color-mix(in srgb, var(--cat-color, var(--gold-light)) 45%, black));
  transform:skewX(15deg); transform-origin:top left;
  transition:left .5s var(--ease), right .5s var(--ease), transform .5s var(--ease);
  pointer-events:none;
}
/* El orden importa: la capa nítida (::before) va ENCIMA de su copia
   difuminada (::after) — antes ambas quedaban en el mismo plano y el blur
   se pintaba arriba, lavando todo el bloque en vez de dar solo un resplandor
   alrededor del borde sesgado nítido, que es lo que se ve en el video.
   El blur ahora es más grande e intenso para el aspecto "bloom" pedido. */
.cat-card::before{ z-index:1; }
.cat-card::after{ z-index:0; filter:blur(46px); opacity:.9; }
/* left en px fijos (no %) para que el panel de color siempre arranque antes
   que el texto (que empieza a 48px del borde de la tarjeta: 26px de padding
   de .cat-card + 22px de .cat-card-text) sin importar el ancho de la tarjeta
   ni si el título ocupa una o dos líneas — con % se quedaba corto cuando el
   título envolvía a una segunda línea, dejando letras fuera del color. */
.cat-card:hover::before, .cat-card:hover::after{ left:14px; right:10px; transform:skewX(0deg); }
.cat-card:hover::after{ opacity:1; }
.cat-card-text{
  position:relative; z-index:2;
  padding:18px 22px; transition:padding .45s var(--ease);
}
.cat-card:hover .cat-card-text{ padding:34px 22px 24px; }
.cat-card h3, .cat-card p{ text-shadow:0 2px 12px rgba(0,0,0,.5); }
/* overflow-wrap: "Almacenamiento" (una sola palabra larga, sin espacio
   donde partir) se salía por el borde de la tarjeta en un rango angosto de
   pantallas de laptop (~1130-1250px, reportado en una pantalla de 11") —
   las demás palabras compuestas (ej. "Gestión aduanal") ya envuelven bien
   porque tienen espacio. Con esto, cualquier palabra que no quepa se parte
   dentro de la caja en vez de desbordarse, sin tener que afinar un
   breakpoint exacto para esta tarjeta en particular. */
/* Causa real del desborde de "Almacenamiento" en el rango ~1130-1280px:
   NO era falta de espacio (el texto necesita ~124px y la tarjeta tiene
   ~200px disponibles, sobra espacio) — era que `word-break:break-word`
   fuerza un punto de corte aunque el texto SÍ quepa en una línea (quirk de
   ese valor en combinación con el layout flex de la tarjeta). Con solo
   `overflow-wrap:break-word` (que únicamente actúa cuando de verdad no
   cabe) el texto vuelve a cerrar en una sola línea como el resto, y de
   paso sigue protegido ante cualquier palabra futura que sí sea demasiado
   larga para la tarjeta. */
.cat-card h3{ font-size:24px; font-weight:800; line-height:1.24; color:var(--cream); overflow-wrap:break-word; }
.cat-card p{ font-size:18.75px; font-weight:500; line-height:1.55; color:rgba(247,251,240,.75); margin-top:10px; }

/* Colores más diferenciados entre sí (antes casi todos caían en la misma familia
   dorado/naranja) — dorado, naranja, verde salvia, azul acero y café quemado,
   cada uno elegido también por lo que evoca el ícono (verde = crecimiento/alianza,
   azul = alcance global, etc.), sin salirse del tono terroso de la marca. */
/* ---- .cats-grid--flat: versión sin el panel sesgado/animado en hover ----
   Usada en Contacto "Contacto directo". El panel de color de .cat-card vive
   inset y sesgado (::before/::after) y solo cubre toda la tarjeta al hacer
   hover — en reposo se ve el fondo casi negro de la tarjeta (#0A1F17)
   alrededor del panel, y ese negro se hace más evidente durante la
   transición de 500ms. El cliente pidió simplificar este bloque en
   particular (la prioridad de Contacto es facilitar el contacto, no el
   efecto visual) y mostrar el dato de una sola vez, sin depender de pasar
   el mouse — se apaga el panel sesgado y se deja un bloque de color sólido
   y fijo, sin negro asomando en ningún momento. El resto de usos de
   .cat-card en el sitio (si los hay) no se tocan. */
.cats-grid--flat .cat-card{ background:var(--cat-color, var(--gold)); }
.cats-grid--flat .cat-card::before, .cats-grid--flat .cat-card::after{ content:none; }
.cats-grid--flat .cat-card:hover{ transform:none; box-shadow:0 16px 32px rgba(11,43,32,.22); }
.cats-grid--flat .cat-card-text{ padding:26px 26px 24px; }
.cats-grid--flat .cat-card:hover .cat-card-text{ padding:26px 26px 24px; }

.cat-card--1{ --cat-color:var(--gold); }
.cat-card--2{ --cat-color:var(--terracotta); }
.cat-card--3{ --cat-color:#6E8F52; }
.cat-card--4{ --cat-color:#4A7FA5; }
.cat-card--5{ --cat-color:var(--espresso-soft); }

/* ============ RESPALDO / STATS ============ */
/* Espaciados (padding/gap/margin) convertidos a clamp() junto con las letras
   — antes solo el texto se achicaba con el ancho, pero el aire alrededor
   (gap entre columnas, padding de la sección) se quedaba fijo en píxeles,
   así que a medida que la ventana crecía las columnas se separaban mucho
   más de lo que el texto crecía — el bloque se "estiraba" en vez de
   escalar completo, como una forma con el ancho/alto desbloqueados en un
   editor de imágenes. Con todo en clamp(), el bloque entero (letra + aire)
   crece y se achica junto, en proporción — igual que una forma con esa
   relación bloqueada. El piso de cada clamp usa el mismo valor que ya
   tenía la media query de mobile, así que en pantallas angostas se ve
   exactamente igual que antes; solo cambia el tramo de en medio. */
.stats{ background:var(--espresso); padding:clamp(44px,3.2vw,60px) 0 clamp(36px,2.6vw,48px); color:var(--cream); }
.stats-head{ text-align:left; margin-bottom:clamp(32px,2.67vw,48px); max-width:900px; }
.stats-head .eyebrow{ justify-content:center; color:var(--gold-light); }
.stats-head .eyebrow::before{ background:var(--gold-light); }
.stats-title{ font-family:var(--display); font-weight:800; font-size:clamp(21px,1.89vw,34px); line-height:1.32; color:var(--cream); }
.stats-title span{ display:block; margin-top:10px; font-weight:500; font-size:.62em; line-height:1.5; color:rgba(247,251,240,.6); }
/* flex + wrap en vez de grid de 5 columnas fijas: cuando la fila no alcanza
   para las 5 (pantallas medianas/angostas) y sobran elementos para la
   última fila, justify-content:center los centra solos — con grid, esos
   elementos sobrantes se quedaban pegados a la izquierda (reportado: "no
   están centrados"). Cada .stat tiene un ancho mínimo/máximo con flex-basis
   en vez de una fracción fija de columna, así el número de items por fila
   se ajusta solo al espacio real disponible. */
.stats-grid{ display:flex; flex-wrap:wrap; justify-content:center; gap:clamp(10px,1vw,18px); }
.stat{ text-align:center; padding:0 8px; flex:1 1 140px; max-width:200px; }
.stat-num{ font-family:var(--display); font-weight:800; font-size:clamp(26px,2.11vw,38px); color:var(--gold-light); display:flex; align-items:baseline; justify-content:center; gap:2px; }
.stat-label{ font-size:clamp(14.5px,1.04vw,18.75px); color:rgba(247,251,240,.68); margin-top:8px; line-height:1.4; font-weight:600; }
.stat-div{ display:none; }
/* Gráfica decorativa: refuerza visualmente la idea de crecimiento sin depender
   de una librería — un solo <path> de relleno con degradado y otro de trazo
   encima, ambos generados a mano sobre el mismo viewBox. */
.stats-chart{ margin-top:52px; height:clamp(90px,8.33vw,150px); }
.stats-chart svg{ width:100%; height:100%; display:block; overflow:visible; }
.stats-chart-line{ stroke:var(--gold-light); stroke-width:2.5; stroke-linecap:round; }

/* ============ BRAND STATEMENT (bloque tipo "Creating Opportunities") ============ */
.brand-statement{ background:var(--terracotta); overflow:hidden; }
.statement-grid{ display:grid; grid-template-columns:.85fr 1.15fr; align-items:center; min-height:360px; gap:clamp(24px,2.22vw,40px); }
.statement-graphic{
  position:relative; height:100%; min-height:360px; display:flex; align-items:center; overflow:hidden;
  user-select:none;
}
.statement-graphic svg{ width:clamp(220px,23.3vw,420px); height:auto; flex:0 0 auto; }
.statement-text h2{ color:var(--white); font-size:clamp(26px,2.11vw,38px); line-height:1.16; margin-bottom:18px; max-width:16ch; }
.statement-text .accent-word{ color:var(--gold); }
.statement-text p{ color:rgba(247,251,240,.86); font-size:19.4px; margin-bottom:26px; max-width:46ch; font-weight:500; }

/* ============ SERVICIOS (tipo "Products & Services" de Olam) ============ */
.services{ padding:clamp(40px,3.4vw,60px) 0; }
.services-grid{ display:grid; grid-template-columns:.9fr 1.1fr; gap:clamp(32px,3.33vw,60px); align-items:stretch; }
/* No tenía tamaño propio: heredaba el h2 por default del navegador (~24px),
   minúsculo al lado de una foto tan grande — por eso se veía "chiquito". */
.services-intro h2{ font-size:clamp(28px,2.22vw,40px); line-height:1.15; }
.services-intro p{ color:var(--ink-soft); font-size:18.1px; margin:16px 0 26px; max-width:40ch; font-weight:500; }
.services-intro .btn-dark{ padding:19px 34px; font-size:17px; }
/* Galería interactiva: cada punto de la lista tiene su propia foto apilada
   aquí debajo (crossfade de opacidad); al pasar el cursor sobre un punto,
   cambia la foto — igual que viste en la página de Olam. */
.services-photo-wrap{ position:relative; margin-bottom:26px; aspect-ratio:4/3; --corner:44px; border-radius:0 var(--corner) 0 0; overflow:hidden; transition:border-radius .4s var(--ease); }
.services-grid:hover .services-photo-wrap{ --corner:72px; }
.services-photo{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .5s ease; }
.services-photo.active{ opacity:1; }

/* Antes esto era una caja con borde y fondo gris (se sentía "una caja dentro de
   otra caja", genérico, desconectado del resto de la página). Ahora es una lista
   limpia sin marco, pero con affordance real de interacción: fondo + barra de
   acento al hover/activo, para que se sienta clicable de verdad — no solo texto. */
/* align-items:stretch en .services-grid hace que esta columna tome la misma
   altura que la foto de la izquierda; justify-content:center mantiene los 4
   puntos agrupados de forma natural (como estaban) pero centrados dentro de
   esa altura completa, en vez de arrancar pegados arriba. */
.services-list{ display:flex; flex-direction:column; justify-content:center; }
.service-item{
  display:flex; align-items:center; gap:18px; padding:20px 18px;
  border-bottom:1px solid var(--line); position:relative;
  transition:background .3s var(--ease), padding-left .3s var(--ease);
}
.service-item::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--terracotta); transform:scaleY(0); transition:transform .3s var(--ease);
}
.service-item:hover, .service-item.is-active{ background:var(--cream-2); padding-left:26px; }
.service-item:hover::before, .service-item.is-active::before{ transform:scaleY(1); }
.service-item .service-text{ display:flex; flex-direction:column; gap:4px; }
.service-item .desc{ font-size:18.1px; color:var(--ink-soft); font-weight:500; max-width:52ch; }
.service-ico{
  width:80px; height:80px; flex:0 0 auto; border-radius:50%; border:1.5px solid var(--terracotta);
  display:flex; align-items:center; justify-content:center; color:var(--terracotta);
  background:var(--white);
  transition:all .35s var(--ease);
}
.service-item:hover .service-ico, .service-item.is-active .service-ico{ border-color:var(--terracotta-dark); color:var(--terracotta-dark); background:color-mix(in srgb, var(--terracotta) 8%, white); transform:scale(1.06); }
.service-ico svg{ width:58px; height:58px; }
.service-item span.label{ font-weight:800; font-size:18.1px; color:var(--espresso); }
.service-item--accent span.label{ color:var(--terracotta-dark); }

/* ============ ABOUT (tipo "Firm Foundations") ============ */
/* Imagen completa (todo el ancho de la página), tipo el bloque de Olam que
   enviaste como referencia: foto de fondo, texto abajo sobre un degradado
   oscuro, esquina curva grande. Sin tarjeta flotante — la foto ES el fondo. */
.feature-band{ position:relative; margin:0 0 148px; }
.feature-photo{ position:relative; height:620px; overflow:hidden; --corner:110px; border-radius:0 var(--corner) 0 0; }
.feature-photo img{ width:100%; height:100%; object-fit:cover; }
.feature-photo::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(0deg, rgba(6,21,15,.8) 0%, rgba(6,21,15,.35) 42%, rgba(6,21,15,0) 68%);
}
.feature-overlay{ position:absolute; inset:0; display:flex; align-items:flex-end; padding-bottom:52px; }
.feature-grid{ display:grid; grid-template-columns:1.2fr .8fr; gap:clamp(28px,3.11vw,56px); align-items:end; width:100%; }
.feature-main h2{ color:var(--cream); font-size:clamp(27px,2.11vw,38px); line-height:1.2; max-width:17ch; margin-bottom:24px; text-shadow:0 2px 14px rgba(0,0,0,.55); }
.feature-main .accent-word{ color:var(--gold-light); }
.feature-points{ display:flex; flex-direction:column; gap:clamp(16px,1.22vw,22px); }
/* Mismo recurso que .cat-card h3/p (arriba): la foto de fondo tiene zonas
   claras (cielo, lona del camión) donde el texto perdía contraste aunque
   ya hubiera degradado oscuro debajo — un text-shadow lo separa del fondo
   sin importar qué haya detrás, sin agregar una caja/tarjeta nueva. */
.feature-point h4{ color:var(--gold-light); font-size:19.2px; font-weight:800; margin-bottom:6px; text-shadow:0 1px 10px rgba(0,0,0,.65); }
.feature-point p{ color:rgba(247,251,240,.85); font-size:18px; font-weight:500; text-shadow:0 1px 10px rgba(0,0,0,.65); }

/* ============ TARJETAS CON REVELADO EN HOVER (referencia del cliente) ============
   Reemplaza el patrón .cats-grid (tarjetas de color diagonal, siempre con el
   mismo texto visible) en las secciones marcadas como "muy repetitivo".
   Aclarado por el cliente tras 2 intentos: LAS 3 tarjetas arrancan con foto
   (no solo 2 de 3) — al pasar el mouse, un panel de color SÓLIDO barre de
   abajo hacia arriba cubriendo casi toda la tarjeta (no una franja chica),
   y el título+texto quedan sobre ese color. flex+wrap con justify-content:
   center (no grid) para que cualquier tarjeta sobrante en la última fila
   quede centrada, sin importar cuántas sean. */
.reveal-cards{ display:flex; flex-wrap:wrap; justify-content:center; gap:clamp(14px,1.11vw,20px); }
.reveal-card{
  position:relative; overflow:hidden; isolation:isolate;
  flex:1 1 260px; max-width:360px;
  /* clamp en vez de 380px fijo — mismo motivo que .cat-card: en 1 columna
     (ancho completo) un alto fijo sobra muchísimo para un texto corto. */
  min-height:clamp(220px,22vw,380px); display:flex; align-items:flex-end;
  --corner:52px; border-radius:0 var(--corner) 0 0;
  transition:transform .4s var(--ease), box-shadow .4s var(--ease);
}
.reveal-card:hover{ transform:translateY(-6px); box-shadow:0 26px 48px rgba(11,43,32,.28); }
.reveal-card img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }
.reveal-card::before{
  content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(0deg, rgba(6,21,15,.85) 0%, rgba(6,21,15,.15) 60%, rgba(6,21,15,0) 100%);
}
/* El panel de color: empieza empujado 100% hacia abajo (invisible) y sube a
   su posición normal en hover — como una cortina. z-index 2, entre la foto
   (0-1) y el texto (3), así el texto siempre queda legible encima sin
   importar si el panel ya subió o no. */
.reveal-card-wipe{
  position:absolute; inset:0; z-index:2;
  background:var(--card-color, var(--terracotta));
  transform:translateY(100%);
  transition:transform .5s var(--ease);
}
.reveal-card:hover .reveal-card-wipe{ transform:translateY(0); }
.reveal-card-body{ position:relative; z-index:3; padding:26px; width:100%; }
.reveal-card-body h3{ font-size:22px; font-weight:800; line-height:1.25; color:var(--cream); text-shadow:0 2px 12px rgba(0,0,0,.35); }
/* --rc-accent: override opcional por tarjeta (ver reveal-card en el HTML) —
   necesario para la tarjeta con fondo --gold (Calidad "Control documental"),
   donde el dorado-claro por default quedaba casi del mismo tono que el
   fondo y la palabra se volvía ilegible. */
.reveal-card-body h3 .accent-word{ color:var(--rc-accent, var(--gold-light)); }
.reveal-card-p-wrap{ overflow:hidden; max-height:0; transition:max-height .45s var(--ease) .1s; }
.reveal-card:hover .reveal-card-p-wrap{ max-height:190px; }
.reveal-card-body p{
  margin-top:12px; font-size:17.5px; font-weight:500; line-height:1.55;
  color:rgba(247,251,240,.9);
  opacity:0; transition:opacity .35s ease .15s;
}
.reveal-card:hover .reveal-card-body p{ opacity:1; }

/* ============ CIERRE / CONTACTO — bloque completo, tipo "Talk to Us" de Olam ============ */
/* Ancho completo de verdad (se sale del .container con el truco 100vw), con
   nuestra curva de firma cruzando toda la parte de arriba, y todo centrado:
   icono, título, texto y botón — no una tarjeta con texto a la izquierda. */
.contact-band{
  position:relative; width:100vw; margin-left:calc(50% - 50vw);
  background:var(--espresso); color:var(--cream);
  clip-path:url(#topCurve);
  padding:110px 24px 120px;
}
.contact-inner{
  max-width:560px; margin:0 auto; display:flex; flex-direction:column; align-items:center; text-align:center;
}
.contact-icon{
  display:flex; align-items:center; justify-content:center; margin-bottom:22px; color:var(--terracotta);
}
.contact-icon svg{ width:72px; height:72px; }
.contact-inner h3{ color:var(--cream); font-size:clamp(24px,1.78vw,32px); margin-bottom:14px; }
.contact-inner p{ font-size:18.75px; color:rgba(247,251,240,.78); margin:0 0 30px; max-width:44ch; font-weight:500; }
.contact-band .btn-pill:hover{ background:var(--gold); }

/* ============ FOOTER ============ */
.site-footer{ background:var(--espresso); color:var(--cream-2); padding:clamp(48px,4vw,72px) 0 clamp(20px,1.56vw,28px); }
.footer-top{ display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr; gap:clamp(24px,2.22vw,40px); padding-bottom:clamp(32px,2.67vw,48px); border-bottom:1px solid rgba(255,255,255,.1); }
.footer-brand .brand-word{ color:var(--cream); }
.footer-firma{ font-size:17.5px; color:rgba(255,255,255,.6); margin-top:16px; max-width:32ch; font-weight:500; }
.footer-social{ display:flex; gap:10px; margin-top:22px; }
.footer-social a{ width:34px; height:34px; border-radius:50%; border:1px solid rgba(255,255,255,.2); display:flex; align-items:center; justify-content:center; transition:background .3s, border-color .3s; }
.footer-social a:hover{ background:var(--gold); border-color:var(--gold); }
.footer-social svg{ width:15px; height:15px; }
.footer-col h5{ font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:var(--gold-light); margin:0 0 18px; font-weight:800; }
.footer-col ul{ display:flex; flex-direction:column; gap:11px; }
.footer-col a{ font-size:14px; color:rgba(255,255,255,.72); transition:color .25s; font-weight:500; }
.footer-col a:hover{ color:var(--white); }
.footer-bottom{ display:flex; justify-content:space-between; align-items:center; padding-top:26px; font-size:12.5px; color:rgba(255,255,255,.45); flex-wrap:wrap; gap:12px; font-weight:500; }

/* ============ BANNER DE COOKIES ============
   2026-09-25: pedido del cliente, brief V5 pág. 18 ("consentimiento de
   cookies según corresponda"). Barra fija abajo, se guarda la decisión en
   localStorage (`volt-cookie-consent`) para no volver a mostrarla — sin
   backend, sin datos del cliente, 100% frontend. Se muestra en las 8
   páginas vía el mismo script en `main.js`. */
.cookie-banner{
  position:fixed; left:16px; right:16px; bottom:16px; z-index:200;
  max-width:760px; margin:0 auto;
  background:var(--espresso); color:var(--cream);
  border-radius:0 24px 0 24px; padding:22px 26px;
  display:flex; flex-wrap:wrap; gap:16px 24px; align-items:center; justify-content:space-between;
  box-shadow:0 20px 48px rgba(20,16,10,.35);
  translate:0 140%; transition:translate .5s var(--ease);
}
.cookie-banner.is-visible{ translate:0 0; }
.cookie-banner p{ font-size:14.5px; line-height:1.55; color:rgba(247,251,240,.85); font-weight:500; margin:0; flex:1 1 260px; }
.cookie-banner a{ color:var(--gold-light); text-decoration:underline; }
.cookie-banner-actions{ display:flex; gap:10px; flex:0 0 auto; }
.cookie-banner-actions button{
  font-family:inherit; font-weight:700; font-size:14.5px; cursor:pointer;
  border-radius:20px; padding:10px 20px; transition:opacity .2s;
}
.cookie-banner-actions button:hover{ opacity:.85; }
.cookie-accept{ background:var(--gold); color:var(--espresso); border:none; }
.cookie-reject{ background:none; color:var(--cream-2); border:1px solid rgba(255,255,255,.3); }
@media (max-width:600px){
  .cookie-banner{ flex-direction:column; align-items:stretch; text-align:left; padding:20px; }
  /* En columna, el flex-basis:260px del párrafo pasaba a ser su ALTO (no su ancho) y
     dejaba un hueco enorme entre el texto y los botones. Aquí el párrafo toma su alto natural. */
  .cookie-banner p{ flex:0 0 auto; }
  .cookie-banner-actions{ width:100%; }
  .cookie-banner-actions button{ flex:1; }
}

/* ============ PÁGINAS INTERIORES — piezas reutilizables ============
   Header, footer y contact-band se copian idénticos de index.html en cada
   página (no se tocan). Todo lo de aquí es para el contenido de EN MEDIO:
   algunas piezas (doors, services, stats, feature-band, brand-statement...)
   ya existen arriba y se reusan tal cual con contenido distinto; esto de
   aquí es lo que hacía falta agregar: un hero de página interior (sin
   carrusel ni pinned-scroll, esos son solo del home), migas de pan, una
   cuadrícula de "motivos" con ícono, una franja oscura de "estándares", y
   un formulario. */

/* ---- Hero de página interior: mismo lenguaje visual (bloque de color +
   foto con la curva de marca), pero estático — sin el carrusel ni el
   scroll fijo del home, que son mecánicas exclusivas de portada. ---- */
/* padding-top:134px + min-height subido de 460 a 594 (460+134): ahora que
   .header-group es fixed (ver esa nota), ya no reserva su propio espacio en
   el flujo, así que este Hero tiene que hacerlo él mismo — 134px es el alto
   del header EXPANDIDO (con la barra de utilidad), el mismo valor fijo que ya
   usa .hero-inner en portada. .page-hero-photo (más abajo) sigue con
   inset:0 sin tocar: como box-sizing es border-box, ese padding-top ya está
   incluido en los 594px totales, así que la foto (que ignora el padding, por
   ser position:absolute) sigue mostrando los mismos 460px visibles de
   siempre debajo del header — el layout se ve IDÉNTICO a antes, solo que
   ahora el espacio lo reserva el propio Hero en vez del header. */
/* min-height pasó de fijo (594px) a min(594px,78vh): 594px es el alto
   pensado para una ventana de escritorio normal, pero al ser un valor fijo
   en píxeles nunca se achicaba en una ventana más baja (o una laptop con
   poco alto de pantalla) — ahí el banner se comía casi toda la primera
   vista sin dejar ver nada del contenido de abajo, aunque en una ventana
   más alta el mismo banner se viera proporcionalmente chico (reportado con
   2 capturas del mismo navegador, solo cambiando el alto de la ventana).
   Con el tope en 78vh, en pantallas bajas el banner se achica junto con la
   ventana; en una ventana normal/alta (78vh > 594px, o sea más de ~761px
   de alto) se queda exactamente igual que antes. */
.page-hero{
  position:relative; overflow:hidden;
  background:var(--terracotta); color:var(--cream);
  min-height:min(594px, 78vh); padding-top:134px; display:flex; align-items:center;
}
/* Anclas del mega menú (Proveedores/Alianzas → secciones específicas de su
   página, no solo el tope): el header es position:fixed y flota ENCIMA del
   contenido, así que sin esto un enlace a #estandares dejaba el título
   tapado detrás del header al llegar. scroll-margin-top empuja el punto de
   destino hacia abajo esa misma altura antes de centrar el scroll ahí —
   funciona con el scroll-behavior:smooth ya activo en <html>, así que el
   salto además llega deslizándose, no de golpe. */
/* Mismo motivo que antes estaba documentado solo para .world-map-band: para
   cuando el scroll automático al ancla se dispara, el movimiento mismo ya
   hizo que la barra de utilidad de arriba se oculte (se oculta apenas hay
   scroll, ver "scrolled" en main.js) — así que el header real en ese
   momento siempre es el COLAPSADO (82px), nunca el expandido (134px). Usar
   134px en el resto de las secciones (antes solo .world-map-band tenía el
   valor correcto) dejaba de más ese mismo hueco en blanco reportado — el
   salto quedaba corto, con espacio de sobra antes del título. */
.reasons, .doors, .standards, .steps, .form-section, .world-map-band, .services, .diag-split{ scroll-margin-top:82px; }
.page-hero-photo{ position:absolute; inset:0; z-index:0; clip-path:url(#heroCurve); }
.page-hero-photo img{ width:100%; height:100%; object-fit:cover; }
/* Calidad: archivo recortado ANCHO (relación ~2.6:1, parecida a la del
   propio banner) para que object-fit:cover apenas tenga que agrandarlo. El
   sujeto ya quedó colocado dentro del propio archivo al recortarlo, así que
   aquí basta con centrar verticalmente. */
#hero-calidad .page-hero-photo img{ object-position:50% 68%; }
/* Alianzas — caso aparte: la foto es una imagen generada por IA de solo
   1375x768px (no hay una versión de mayor resolución disponible), y el
   banner se dibuja a casi 1900px de ancho — agrandarla con object-fit:cover
   la dejaba notablemente borrosa/pixelada (agrandado real de ~40%). Como la
   curva solo deja ver el 58% izquierdo del ancho del banner como máximo
   (como mucho ~1100-1300px en pantallas normales), el archivo de 1375px ya
   alcanza a cubrir esa zona sin necesidad de agrandarlo ni un pixel —
   object-fit:none deja la foto a su tamaño real (sin estirar) anclada a la
   izquierda, así que se ve nítida. En monitores extra anchos (fuera de lo
   común) podría quedar una franja sin foto justo en el borde de la curva;
   es el trade-off aceptado a cambio de nitidez real. */
#hero-alianzas .page-hero-photo img{
  max-width:none;
  object-fit:none; object-position:-280px 38%;
}
/* Con object-fit:none el corrimiento es en PÍXELES fijos, no relativos — en
   una ventana de escritorio más angosta (ej. laptop de 13") el ancho visible
   de la curva (que sí es proporcional al ancho de pantalla) se encoge más
   rápido de lo que se encoge el corrimiento fijo, así que la cabina se volvía
   a salir de la zona visible (reportado con capturas en una ventana más
   chica que la de antes). Estos 2 escalones angostan el corrimiento más
   mientras más angosta la ventana, calculado con la misma geometría de la
   curva — arriba de 1600px el valor base de arriba ya es suficiente. */
@media (min-width:931px) and (max-width:1300px){
  #hero-alianzas .page-hero-photo img{ object-position:-520px 38%; }
}
@media (min-width:1301px) and (max-width:1600px){
  #hero-alianzas .page-hero-photo img{ object-position:-420px 38%; }
}
.page-hero-photo::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(200deg, rgba(11,43,32,.16), rgba(11,43,32,0) 45%);
}
/* Solo padding vertical aquí a propósito (ver el mismo comentario en
   .hero-inner) — el horizontal lo hereda de .container. */
/* text-align:right — de vuelta como estaba en escritorio y en el rango
   "tablet" que todavía tiene la foto con curva (aquí SÍ se queda a la
   derecha, confirmado que se ve bien). La asimetría reportada no era por
   la dirección del texto, era porque el párrafo tenía un max-width distinto
   al del título (ver más abajo, esa parte del fix SÍ se queda) — con las 3
   cajas midiendo lo mismo, right-align ya no se ve "dentado". Solo la
   versión apilada real (foto arriba, sin curva, ver @media 860px) sigue
   alineada a la izquierda, como ya estaba desde antes. */
.page-hero-inner{ position:relative; z-index:2; width:100%; padding-top:80px; padding-bottom:64px; text-align:right; }
.breadcrumb{ display:flex; justify-content:flex-end; gap:8px; font-size:13.5px; font-weight:600; color:rgba(247,251,240,.75); margin:0 0 20px; }
.breadcrumb a{ color:rgba(247,251,240,.75); transition:color .2s; }
/* El cambio de color solo (cream translúcido → cream sólido) es una
   diferencia demasiado sutil para notarse como hover real, sobre todo
   encima de la foto — se le suma un subrayado, como el resto de los links
   del sitio, para que sea inequívoco. */
.breadcrumb a:hover{ color:var(--cream); text-decoration:underline; text-underline-offset:3px; }
.breadcrumb span{ color:rgba(247,251,240,.4); }
/* max-width subió de 660px fijo a min(720px,52vw) — a pedido del cliente,
   660px hacía que algunos títulos (ej. "No es necesario dividir en dos
   líneas") envolvieran a más líneas de las necesarias. Se probó primero con
   54vw/760px, pero medido contra la curva real (heroCurve, misma curva que
   el Hero de portada, llega máximo al 58% del ancho de pantalla en la base
   de la foto) el margen quedaba muy justo (12.7px en 862px de ancho) —
   52vw/720px deja bastante más margen (29.9px en el mismo ancho) y sigue
   reduciendo el título a menos líneas que antes. */
.page-hero h1{ font-size:clamp(34px,3vw,54px); line-height:1.08; margin:0 0 20px; color:var(--cream); font-weight:800; max-width:min(720px,52vw); margin-left:auto; }
.page-hero h1 .accent-word{ color:var(--gold); }
/* Oportunidades: "Oportunidades de negocio en el mercado alimentario
   mexicano." se partía en 2 líneas sin necesidad con el tope general de
   720px/52vw — pedido del cliente, mismo criterio ya usado en #puertas
   (Home): ensanchar solo esta h1 en vez de tocar el tope de todas las
   páginas que usan .page-hero. */
/* Un solo valor de max-width NO alcanza en todo el rango de escritorio: el
   font-size de este h1 crece con la pantalla y a mayor tamaño de letra el
   texto necesita un ancho MÍNIMO más grande para seguir entrando en 2
   líneas balanceadas — pero al mismo tiempo el ancho no puede pasarse de
   cierto máximo o el borde izquierdo invade la curva naranja de la foto
   (pasado ~1408px .container llega a su ancho MÁXIMO fijo, 1320px, y deja
   de crecer con la pantalla, pero la curva —ancho completo del viewport,
   sin ese tope— se sigue corriendo a la derecha).
   2026-09-24: la primera versión de este fix (4 escalones sobre el clamp
   original de 34-54px) SÍ tenía huecos reales sin margen de sobra —
   verificado con getBoundingClientRect() a lo largo de TODO el rango
   1301-2560px (no solo en 4 puntos "representativos") se encontraron dos
   zonas imposibles: 1081-1150px (una franja completa sin ningún max-width
   que evitara el traslape, resuelta aparte apilando la sección antes, ver
   @media 1150px arriba) y 1701-1920px (donde ningún valor daba a la vez 2
   líneas Y margen positivo — el font-size tocaba su tope de 54px justo
   ahí, exigiendo más ancho del que la curva dejaba disponible). La causa
   de la segunda zona: el font-size llegaba a su límite superior (54px) muy
   cerca de donde el ancho disponible se vuelve más ajustado. Bajar el tope
   del clamp a 50px (en vez de 54px, SOLO para este título) mueve ese punto
   crítico a un rango donde sí sobra margen, y con eso 2 escalones (en vez
   de 4) alcanzan para todo el rango 1301-2560+ con margen real (12-138px)
   en cada punto probado. */
#hero-oportunidades h1{ max-width:640px; font-size:clamp(34px,3vw,50px); }
/* 2026-09-24: al bajar el quiebre de una columna de 1150px a 930px (pedido
   del cliente), el rango 931-1150px pasó a usar la curva diagonal y el
   max-width base (640px) volvía a invadirla ahí (mismo problema de fondo
   que ya se había resuelto para 1301+ arriba) — se agregan 3 escalones
   angostos más, cada uno verificado con getBoundingClientRect() en el
   extremo más ajustado de su rango: */
@media (min-width:931px){ #hero-oportunidades h1{ max-width:520px; } }
@media (min-width:1000px){ #hero-oportunidades h1{ max-width:560px; } }
@media (min-width:1080px){ #hero-oportunidades h1{ max-width:600px; } }
@media (min-width:1301px){ #hero-oportunidades h1{ max-width:740px; } }
@media (min-width:1601px){ #hero-oportunidades h1{ max-width:770px; } }
/* max-width igual al de h1 (antes tenía además un tope de 52ch, pensado
   para legibilidad) — con un tope distinto al de h1/hero-actions, esta caja
   terminaba más angosta que las otras dos, y como las 3 siguen ancladas al
   borde derecho (margin-left:auto, el bloque completo se queda del lado de
   la foto), una caja más angosta arrancaba más a la derecha que las otras
   — eso era la asimetría real, no el text-align. Con el mismo max-width
   las 3 cajas miden lo mismo y arrancan exactamente en el mismo punto. */
.page-hero p{ max-width:min(720px,52vw); margin-left:auto; font-size:18.1px; color:rgba(247,251,240,.86); font-weight:500; margin-bottom:0; }
/* --btn-guard-shift: mismo mecanismo y mismo motivo que en el Hero de
   portada (ver comentario junto a .hero-actions más arriba) — el botón es
   una caja sólida y se ve rozar la curva aunque el texto, con el mismo
   ancho, nunca la toca. En vez de restarle un número fijo de píxeles a
   ciegas (frágil: cambiaba con el idioma y el ancho de pantalla), main.js
   mide en tiempo real el borde de la curva a la altura de los botones y
   angosta SOLO esta fila lo justo. 0px por defecto = idéntico a antes. */
.page-hero .hero-actions{ padding-top:30px; max-width:calc(min(720px,52vw) - var(--btn-guard-shift, 0px)); margin-left:auto; flex-wrap:wrap; }
/* El contenedor ya tenía max-width, pero el BOTÓN en sí (.btn base) usa
   white-space:nowrap y un padding/letra fijos — con un texto largo (ej.
   portugués, "Vamos conversar sobre sua entrada") el botón sigue siendo más
   ancho que los 660px del contenedor sin importar la pantalla, y como los
   flex-items no se encogen solos por debajo de su contenido, se sale por la
   izquierda encima de la foto. Mismo arreglo que ya tiene el Hero de
   portada: el botón se achica solo (clamp con vw) en pantallas angostas, y
   min-width:0 + white-space:normal es el respaldo final — si aun encogido
   al mínimo no cupiera, el texto se parte en dos líneas DENTRO del botón en
   vez de desbordarlo. */
.page-hero .hero-actions .btn{
  font-size:clamp(13px,1.3vw,16.5px); padding:clamp(10px,1.65vw,17px) clamp(14px,2.5vw,30px);
  white-space:normal; min-width:0; text-align:center;
}
.page-hero .btn-text{ color:var(--cream); }
.page-hero .btn-text:hover{ color:var(--espresso); }

/* ---- Motivos / value props: tarjetas editoriales con acento superior ----
   Antes cada tarjeta llevaba un ícono en un círculo (.reason-ico) — con el
   mismo círculo repetido en 4 páginas distintas (Calidad, Contacto,
   Alianzas, Oportunidades) terminaba viéndose como un "sticker" genérico
   de plantilla, no como algo diseñado para VOLT. Se quita el ícono y en su
   lugar el título lleva un trazo corto en terracota encima — el mismo
   recurso que ya usa .stat-div en la franja de cifras, así que no es un
   patrón nuevo, es reutilizar uno que ya existe en el sitio. */
.reasons{ padding:clamp(40px,3.4vw,60px) 0; }
/* 2026-09-24: "¿Qué aporta cada parte?" (Oportunidades) se veía "muy
   blanco" — pedido del cliente: fondo sólido oscuro (el mismo café-espresso
   ya usado en los diferenciadores), con las siluetas de montaña del logo
   dispersas detrás como marca de agua, y la tarjeta .compare2 reducida al
   ~70% del ancho y centrada (ya no de borde a borde). */
.reasons--tinted{ background:var(--espresso); }
.reasons--tinted .section-head{ max-width:640px; margin-left:auto; margin-right:auto; text-align:center; }
.reasons--tinted .section-head h2{ color:var(--cream); }
.reasons--tinted .section-head p{ color:var(--cream-2); margin-left:auto; margin-right:auto; }
.reasons--tinted .container{ position:relative; z-index:1; }
.reasons-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:34px 28px; margin-top:46px; }
.reason-card{ display:flex; flex-direction:column; gap:10px; }
.reason-card h3{
  font-size:19px; font-weight:800; color:var(--espresso);
  position:relative; padding-top:20px;
}
.reason-card h3::before{
  content:""; position:absolute; top:0; left:0; width:34px; height:3px;
  background:var(--terracotta); border-radius:2px;
}
.reason-card p{ font-size:18.1px; color:var(--ink-soft); font-weight:500; }

/* ---- Franja oscura de estándares / puntos de confianza ---- */
.standards{ background:var(--espresso); color:var(--cream); padding:clamp(56px,4.67vw,84px) 0; }
.standards .section-head h2{ color:var(--cream); }
.standards .section-head p{ color:rgba(247,251,240,.75); }
.standards-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:44px; margin-top:46px; }
.standard-item{ display:flex; gap:20px; }
.standard-ico{
  width:54px; height:54px; border-radius:50%; border:1.5px solid var(--gold-light);
  color:var(--gold-light); display:flex; align-items:center; justify-content:center; flex:0 0 auto;
}
.standard-ico svg{ width:25px; height:25px; }
.standard-item h3{ color:var(--cream); font-size:19px; font-weight:800; margin-bottom:8px; }
.standard-item p{ color:rgba(247,251,240,.8); font-size:18.1px; font-weight:500; }

/* ---- Sección G — foto simple + texto plano (ref. "Reliable Origination" /
   "Nigeria Rice Production") ---- máximo 2 usos en todo el sitio: Oportunidades
   "¿A quién va dirigida esta sección?" (foto a la derecha) y Proveedores
   "Estándares y confidencialidad" (foto a la izquierda) — el orden lo decide
   el orden de los dos hijos en el HTML, no una clase modificadora. Esquina
   única redondeada arriba-derecha en la foto (identidad de marca del sitio),
   el resto en escuadra. */
.simple-photo-band-grid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(32px,4vw,64px); align-items:center; margin-top:8px; }
.simple-photo-band-photo{ aspect-ratio:4/3; border-radius:0 40px 0 0; overflow:hidden; }
.simple-photo-band-photo img{ width:100%; height:100%; object-fit:cover; display:block; }
.simple-photo-band-text h2{ color:var(--cream); font-size:clamp(28px,2.2vw,36px); margin-bottom:20px; }
.simple-photo-band-text h3{ color:var(--cream); font-size:19px; font-weight:800; margin:20px 0 8px; }
.simple-photo-band-text h3:first-of-type{ margin-top:0; }
.simple-photo-band-text p{ color:rgba(247,251,240,.8); font-size:18.1px; font-weight:500; }
@media (max-width:760px){
  .simple-photo-band-grid{ grid-template-columns:1fr; }
  .simple-photo-band-photo{ order:-1; }
}

/* ---- Formulario de precalificación ---- */
.form-section{ padding:clamp(40px,3.4vw,60px) 0; }
.form-grid{ display:grid; grid-template-columns:1.25fr .75fr; gap:clamp(32px,3.33vw,60px); align-items:stretch; }
.form-intro h2{ font-size:clamp(28px,2.11vw,38px); line-height:1.15; margin-bottom:14px; }
.form-intro > p{ color:var(--ink-soft); font-size:18.1px; font-weight:500; margin-bottom:34px; max-width:52ch; }
.prequal-form{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(16px,1.33vw,24px) clamp(18px,1.44vw,26px); }
.field{ display:flex; flex-direction:column; gap:8px; }
.field.full{ grid-column:1/-1; }
.field label{ font-size:13.5px; font-weight:700; color:var(--espresso); }
.field label .req{ color:var(--terracotta); }
.field input, .field select, .field textarea{
  border:0; border-bottom:1.5px solid var(--line-strong); background:transparent;
  padding:11px 2px; font-family:inherit; font-size:15px; color:var(--ink);
  transition:border-color .25s; border-radius:0;
}
.field input:focus, .field select:focus, .field textarea:focus{ outline:none; border-color:var(--terracotta); }
.field textarea{ resize:vertical; min-height:90px; }
.field select{ appearance:none; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236A6258' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 2px center; background-size:16px; }
.prequal-form .btn{ grid-column:1/-1; justify-self:start; margin-top:8px; }
.form-privacy{ grid-column:1/-1; font-size:12.5px; color:var(--ink-soft); font-weight:500; }
/* Mensaje de éxito/error del formulario de contacto (contacto.php vía
   fetch, ver main.js) — vacío y sin tomar espacio hasta que haya un
   resultado que mostrar. */
.form-feedback{ grid-column:1/-1; font-size:14.5px; font-weight:700; margin:0; }
.form-feedback:empty{ display:none; }
.form-feedback.is-ok{ color:#4A7F3C; }
.form-feedback.is-error{ color:#B3402E; }
/* .help-box ahora estira su alto para igualar al formulario (align-items:stretch
   en .form-grid) — antes se quedaba del alto de su propio texto y dejaba un
   tramo grande de página vacía debajo, ya que el formulario de al lado es
   mucho más largo. La foto llena justo ese espacio sobrante, con la curva
   abajo-izquierda como contraparte de la curva arriba-derecha de la tarjeta. */
.help-box{
  background:var(--cream-2); --corner:40px; border-radius:0 var(--corner) 0 0; padding:34px 30px;
  display:flex; flex-direction:column;
}
.help-box h4{ font-size:19px; font-weight:800; margin-bottom:10px; color:var(--espresso); }
.help-box p{ font-size:18.1px; color:var(--ink-soft); margin-bottom:20px; font-weight:500; }
.help-box-photo{
  margin:20px -30px -34px; flex:1; min-height:180px; overflow:hidden;
  border-radius:0 0 0 var(--corner);
}
.help-box-photo img{ width:100%; height:100%; object-fit:cover; display:block; }

/* ---- Proceso numerado (pasos secuenciales) — para "Cómo trabajamos",
   "Nuestro enfoque de control", "Nuestra operación de punta a punta", etc.
   Mismo lenguaje que .reason-card/.standard-item (número en vez de ícono, la
   curva de marca en la esquina) para que se sienta parte de la misma familia
   sin ser una copia exacta de los otros bloques. */
.steps{ padding:clamp(40px,3.4vw,60px) 0; }
/* Empresa: título y párrafo del banner son cortos (a diferencia de otras
   páginas), así que no necesita tanto aire fijo antes de "Nuestra
   evolución" — reportado por el cliente como "mucho espacio en blanco"
   antes de que aparezca contenido real. Se achica SOLO en esta página
   (por id), sin tocar el resto de los usos de .steps/.page-hero en el
   sitio. */
#hero-empresa{ min-height:min(460px, 62vh); }
#evolucion-empresa{ padding-top:clamp(40px,3.5vw,64px); }
/* Título centrado sobre la tarjeta (que también está centrada, con su
   propio max-width) — .section-head por defecto se queda pegado a la
   izquierda, que se veía descuadrado contra una tarjeta simétrica debajo. */
.steps .section-head{ text-align:center; max-width:none; margin-left:auto; margin-right:auto; }
/* Antes usaba `repeat(auto-fit,minmax(220px,1fr))` — con 4 tarjetas, en un
   rango de ancho donde solo caben 3 columnas, la 4ª quedaba sola pegada a
   la izquierda en su propia fila (el grid reserva las mismas 3 columnas en
   todas las filas). Se cambió a columnas fijas por breakpoint (2 y 1) para
   que nunca quede una tarjeta suelta sin centrar — mismo criterio que
   `.hover-reveal-grid`. */
.steps-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(18px,1.44vw,26px); margin-top:clamp(32px,2.56vw,46px); }
@media (max-width:980px){
  .steps-grid{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:560px){
  .steps-grid{ grid-template-columns:1fr; }
}
.step-card{
  background:var(--cream-2); padding:32px 26px 28px;
  --corner:36px; border-radius:0 var(--corner) 0 0;
  transition:border-radius .35s var(--ease);
}
.step-card:hover{ --corner:60px; }
.step-num{
  display:flex; align-items:center; justify-content:center; width:38px; height:38px;
  border-radius:50%; border:1.5px solid var(--terracotta);
  font-family:var(--display); font-size:15px; font-weight:800; color:var(--terracotta);
  margin-bottom:18px;
}
.step-card h3{ font-size:19px; font-weight:800; margin-bottom:8px; color:var(--espresso); }
.step-card p{ font-size:18.1px; color:var(--ink-soft); font-weight:500; }

/* ---- Línea de tiempo horizontal — variante de .steps para narrativas
   cronológicas ("Nuestra evolución"). Puntos simples (sin número: un
   círculo vacío en reposo, relleno cuando está activo) sobre una línea
   fina, con el nombre subrayado al activarse — mismo lenguaje que la
   referencia que pidió el cliente, con los colores propios de la marca. */
.timeline-flow{ display:flex; position:relative; margin-top:46px; }
.timeline-flow::before{
  content:""; position:absolute; top:6px; left:0; right:0; height:1.5px;
  background:linear-gradient(90deg, var(--terracotta), var(--gold-light));
  opacity:.4;
}
.timeline-point{
  position:relative; flex:1; display:flex; flex-direction:column; align-items:center;
  text-align:center; padding:0 10px; gap:13px; background:none; border:none; cursor:pointer;
}
.timeline-point::before{
  content:""; z-index:1; width:12px; height:12px; border-radius:50%;
  background:var(--cream); border:2px solid var(--line-strong);
  transition:background .25s var(--ease), border-color .25s var(--ease), transform .3s var(--ease);
}
.timeline-text h3{
  font-size:18.1px; font-weight:700; color:var(--ink-soft);
  padding-bottom:3px; border-bottom:2px solid transparent;
  transition:color .2s, border-color .2s;
}
/* Cada paso es un botón — clic en cualquiera (no solo el siguiente) cambia
   el panel de detalle de abajo con un cross-fade. El punto activo se ve
   relleno y un poco más grande; su nombre queda subrayado. */
.timeline-point.is-active::before{
  background:var(--terracotta); border-color:var(--terracotta); transform:scale(1.25);
}
.timeline-point.is-active .timeline-text h3{ color:var(--terracotta-dark); border-color:var(--terracotta); }
.timeline-detail{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(24px,2.22vw,40px); align-items:center; margin-top:clamp(28px,2.33vw,42px); }
.timeline-detail-text,
.timeline-detail-photo{
  transition:opacity .32s var(--ease), translate .32s var(--ease), scale .32s var(--ease);
}
.timeline-detail-text.is-fading,
.timeline-detail-photo.is-fading{ opacity:0; translate:0 10px; scale:.985; }
.timeline-detail-text h3{ font-size:clamp(20px,1.39vw,25px); font-weight:800; color:var(--espresso); margin-bottom:12px; }
.timeline-detail-text p{ font-size:19.4px; color:var(--ink-soft); font-weight:500; line-height:1.6; max-width:42ch; }
.timeline-detail-photo{
  aspect-ratio:4/3; border-radius:0 var(--corner,28px) 0 0; overflow:hidden;
  background:var(--gold-pale);
}
.timeline-detail-photo img{ width:100%; height:100%; object-fit:cover; display:block; }

/* Tarjeta que envuelve toda la línea de tiempo + el detalle, con flechas
   prev/next flotando en los bordes. max-width: antes se estiraba hasta el
   ancho completo del contenedor del sitio (1600px) y se veía enorme
   comparada con la referencia — centrada y más angosta se ve más como una
   pieza de diseño y menos como un bloque suelto. */
.evolution-card{
  position:relative; background:var(--cream); border-radius:32px;
  box-shadow:0 30px 70px -34px rgba(11,43,32,.28), 0 2px 14px rgba(11,43,32,.07);
  padding:44px 52px 48px; margin:40px auto 0; max-width:840px;
}
.evolution-card .timeline-flow{ margin-top:0; }
.evolution-card .timeline-detail{ margin-top:clamp(24px,2.22vw,40px); gap:clamp(24px,2.22vw,40px); }
.evolution-card .timeline-detail-photo{ aspect-ratio:auto; height:260px; border-radius:22px; }
.timeline-nav-arrow{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:52px; height:52px; border-radius:50%; border:none; cursor:pointer;
  background:var(--terracotta); color:var(--cream);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 14px 28px -10px rgba(188,100,29,.55);
  transition:background .2s, transform .2s var(--ease);
}
.timeline-nav-arrow:hover{ background:var(--terracotta-dark); transform:translateY(-50%) scale(1.06); }
.timeline-nav-arrow svg{ width:20px; height:20px; }
.timeline-nav-arrow--prev{ left:-26px; }
.timeline-nav-arrow--next{ right:-26px; }

/* ---- Riel de proceso con ícono — variante de .steps para flujos
   operativos ("Nuestra operación de punta a punta"). Íconos de línea
   conectados por una línea punteada horizontal, mismo lenguaje visual que
   .cat-ico/.service-ico ya usados en el sitio. */
.process-rail{ display:flex; margin-top:58px; align-items:flex-start; }
.rail-step{ flex:1; position:relative; text-align:center; padding:0 10px; }
.rail-step:not(:last-child)::after{
  content:""; position:absolute; top:38px; left:calc(50% + 46px); width:calc(100% - 92px); height:0;
  border-top:2px dashed var(--terracotta);
}
.rail-ico{
  position:relative; z-index:1; width:76px; height:76px; border-radius:50%;
  border:1.5px solid var(--terracotta); background:var(--cream);
  display:flex; align-items:center; justify-content:center; margin:0 auto 20px;
}
.rail-ico svg{ width:36px; height:36px; color:var(--terracotta-dark); }
.rail-step h3{ font-size:16.5px; font-weight:800; color:var(--espresso); margin-bottom:6px; }
.rail-step p{ font-size:18px; color:var(--ink-soft); font-weight:500; line-height:1.5; }

/* ---- Riel vertical alternado — variante de .steps para narrativas de rol
   ("Nuestro rol en cada oportunidad"). Filas apiladas a los lados de una
   línea vertical central con puntos numerados. */
.rail-vertical{ position:relative; margin-top:58px; max-width:760px; }
.rail-vertical::before{ content:""; position:absolute; top:6px; bottom:6px; left:50%; width:2px; background:var(--line-strong); transform:translateX(-50%); }
.rail-vertical-item{ position:relative; width:calc(50% - 34px); margin-bottom:38px; }
.rail-vertical-item:last-child{ margin-bottom:0; }
.rail-vertical-item:nth-child(odd){ margin-right:auto; text-align:right; }
.rail-vertical-item:nth-child(even){ margin-left:auto; text-align:left; }
.rail-vertical-num{
  position:absolute; top:0; width:32px; height:32px; border-radius:50%;
  background:var(--terracotta); color:var(--cream); font-family:var(--display); font-weight:800; font-size:14px;
  display:flex; align-items:center; justify-content:center;
}
.rail-vertical-item:nth-child(odd) .rail-vertical-num{ right:-50px; }
.rail-vertical-item:nth-child(even) .rail-vertical-num{ left:-50px; }
.rail-vertical-item h3{ font-size:16.5px; font-weight:800; color:var(--espresso); margin-bottom:6px; }
.rail-vertical-item p{ font-size:18px; color:var(--ink-soft); font-weight:500; line-height:1.5; }

/* ---- Lista horizontal con flechas y texto de apoyo — variante ligera de
   .steps ("Cómo trabajamos"), reutiliza el lenguaje de .sequence-flow. */
.arrow-steps{ display:flex; flex-wrap:wrap; gap:28px 0; margin-top:50px; }
.arrow-steps-item{ display:flex; align-items:flex-start; gap:0; flex:1 1 200px; min-width:200px; }
.arrow-steps-item .arrow-steps-num{ font-family:var(--display); font-weight:800; font-size:15px; color:var(--terracotta); margin-right:10px; }
.arrow-steps-item h3{ font-size:16.5px; font-weight:800; color:var(--espresso); margin-bottom:5px; }
.arrow-steps-item p{ font-size:18px; color:var(--ink-soft); font-weight:500; line-height:1.5; }
.arrow-steps-sep{ display:flex; align-items:center; color:var(--terracotta); font-size:20px; font-weight:400; padding:0 14px; align-self:center; }

/* ---- "¿Qué aporta cada parte?" v3 — réplica del componente "Compare2"
   que mandó el cliente (React/shadcn, Ali Imam). 2 columnas a todo lo
   ancho, sin tarjetas ni bordes — la única diferencia entre columnas es un
   tinte de fondo tenue en la derecha. Esquina superior-derecha curva en el
   bloque completo (la "silueta" de marca del sitio — el original de
   referencia no tenía ninguna esquina curva, pero el resto de componentes
   grandes de VOLT sí, ver .door/.anaquel-card/etc). */
/* 2026-09-24: ajuste pedido por el cliente sobre la v3 — el tinte de fondo
   quedó "muy débil" (casi imperceptible) y las listas se sentían
   "gigantes"/de borde a borde. Se sube el color a una versión sólida (no
   pálida) de dos colores DENTRO de la marca (dorado para VOLT, terracota
   para el socio — dinamismo real, no la misma familia de color repetida),
   se reduce y centra el bloque de texto (antes 480px, ahora 400px, sigue
   con margin:0 auto) y se pasa el texto a crema (el fondo ya no es lo
   bastante claro para texto oscuro). */
.compare2{
  display:grid; grid-template-columns:1fr 1fr; margin:36px auto 0; overflow:hidden;
  max-width:86%; border-radius:32px; position:relative; z-index:1;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.45);
}
.compare2-col{ display:flex; }
.compare2-col--a{ background:var(--gold); }
.compare2-col--b{ background:var(--terracotta); }
/* Antes .compare2-inner tenía un max-width fijo de 400px — en columnas más
   anchas que eso (la mayoría de pantallas) dejaba franjas de color vacías a
   los lados del texto, sin aprovecharse. Ahora ocupa casi todo el ancho de
   su columna (92%) y el padding/alto se redujo para que la tarjeta también
   se vea menos "inflada" verticalmente — eran los 2 huecos reportados. */
.compare2-inner{ max-width:92%; margin:0 auto; padding:clamp(32px,3.2vw,48px) clamp(16px,2vw,28px); width:100%; }
/* min-height reserva SIEMPRE el espacio de 2 líneas (aunque el título real
   quepa en 1), para que ambas columnas empiecen su checklist exactamente a
   la misma altura sin importar si un título es más largo que el otro
   ("Lo que puede aportar el socio" ocupa 2 líneas, "Lo que aporta VOLT"
   solo 1) — pedido del cliente ("las palomitas empiezan más arriba en una
   columna que en la otra"). */
.compare2-title{
  font-size:clamp(27.6px,2.53vw,34.5px); line-height:1.25; text-align:center; margin-bottom:24px;
  min-height:calc(2 * clamp(27.6px,2.53vw,34.5px) * 1.25);
  display:flex; align-items:center; justify-content:center;
}
.compare2-list{ list-style:none; display:flex; flex-direction:column; gap:12px; }
/* align-items:center (no flex-start) — la palomita debe quedar centrada
   verticalmente contra el bloque de texto completo (1 o 2 líneas), no
   pegada arriba contra la primera línea. */
.compare2-list li{ display:flex; align-items:center; gap:14px; }
/* Sin esto, <p> hereda el margen de navegador por default (~1em arriba y
   abajo) — sumado al gap de 12px de la lista, cada palomita quedaba
   separada de la siguiente por casi 3 saltos de línea completos, aunque el
   "gap" configurado fuera chico. Este es el hueco real reportado. */
.compare2-list p{ font-size:20.1px; font-weight:500; margin:0; }
/* Gold (columna VOLT) es un fondo CLARO → texto oscuro; terracota
   (columna socio) es un fondo MEDIO/OSCURO → texto crema. Cada columna
   define su propio color de texto en vez de uno fijo para las dos. */
.compare2-col--a .compare2-title, .compare2-col--a .compare2-list p{ color:var(--espresso); }
.compare2-col--b .compare2-title, .compare2-col--b .compare2-list p{ color:var(--cream); }
.compare2-check{
  flex:0 0 auto; width:22px; height:22px; margin-top:1px; border-radius:50%;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/60% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/60% no-repeat;
}
.compare2-col--a .compare2-check{ background:var(--espresso); }
.compare2-col--b .compare2-check{ background:var(--cream); }
@media (max-width:900px){
  .compare2{ max-width:92%; }
}
@media (max-width:760px){
  .compare2{ grid-template-columns:1fr; border-radius:28px; max-width:100%; }
}

/* ---- Franja de fotos apiladas — variante de .reasons-grid para listas de
   3 con carga fotográfica fuerte ("Nuestro ecosistema operativo"),
   inspirada en la sección "Our products & services" de Olam Agri: cada fila
   es una foto a todo el ancho con texto encima sobre un scrim oscuro. */
.photo-band{ display:flex; flex-direction:column; gap:16px; margin-top:46px; }
.photo-band-row{
  position:relative; overflow:hidden; min-height:172px;
  display:flex; align-items:center; padding:28px 40px; color:var(--cream);
  --corner:28px; border-radius:0 var(--corner) 0 var(--corner);
}
.photo-band-row::before{
  content:""; position:absolute; inset:0; background-image:var(--bg);
  background-size:cover; background-position:center;
}
.photo-band-row::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(24,21,15,.9) 0%, rgba(24,21,15,.62) 50%, rgba(24,21,15,.2) 100%);
}
.photo-band-row > *{ position:relative; z-index:1; }
/* Entrada más marcada que el .reveal genérico (26px, se sentía "solo un
   desvanecido") — pedido del cliente: que se note un deslizamiento franco
   de abajo hacia arriba, fila por fila, no ligado al scroll en sí, solo a
   la transición-delay escalonada por --i que main.js ya asigna en orden de
   aparición (cada fila es su propio .reveal desde este cambio, antes solo
   el wrapper .photo-band lo tenía y las 3 entraban juntas). */
.photo-band-row.reveal{ translate:0 46px; transition:opacity .55s var(--ease), translate .55s var(--ease); }
.photo-band-row.reveal.in{ translate:none; }
/* Retraso explícito por posición, NO el --i global de main.js: ese contador
   se reinicia cada 8 elementos .reveal de TODA la página (i % 8), así que
   si esta sección cae justo después de esa vuelta, el orden real se rompía
   (la 3ª tarjeta llegaba a --i:0 y aparecía ANTES que la 1ª, que le tocó
   --i:6). Con :nth-child fijo el orden 1-2-3 queda garantizado sin importar
   en qué posición de la página caiga el grupo. */
.photo-band-row.reveal:nth-child(1){ transition-delay:0ms; }
.photo-band-row.reveal:nth-child(2){ transition-delay:130ms; }
.photo-band-row.reveal:nth-child(3){ transition-delay:260ms; }
/* Antes cada fila llevaba un ícono en círculo a la izquierda (mismo patrón
   "sticker" que .reason-ico) — se quita el ícono y en su lugar el bloque
   de texto lleva una barra dorada vertical, más discreta y coherente con
   el acento que ya usan las tarjetas .reason-card. */
.photo-band-text{ position:relative; padding-left:22px; }
.photo-band-text::before{
  content:""; position:absolute; left:0; top:3px; bottom:3px; width:3px;
  background:var(--gold-light); border-radius:2px;
}
.photo-band-text h3{ font-size:19px; font-weight:800; margin-bottom:6px; color:var(--cream); }
.photo-band-text p{ font-size:18.1px; font-weight:500; color:rgba(247,251,240,.85); max-width:50ch; }

/* ---- Lista de etiquetas / píldoras — países con operaciones, referencias
   de certificación, canales comerciales, etc. Texto plano, sin logos (no
   validados), pero con más presencia visual que una simple lista separada
   por comas. */
.tag-list{ display:flex; flex-wrap:wrap; gap:10px 12px; }
.tag-list span{
  padding:9px 18px; border:1.5px solid var(--line-strong); border-radius:20px;
  font-size:16.9px; font-weight:700; color:var(--espresso);
}

/* ---- Secuencia horizontal con flechas — "Concepto → Producto → Empaque…" */
.sequence-flow{ display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px; font-size:17px; font-weight:800; color:var(--espresso); }
.sequence-flow .arrow{ color:var(--terracotta); font-weight:400; }
/* Variantes "light": mismo componente pero sobre fondo oscuro/foto (ver
   .anaquel-band) — texto crema en vez de espresso, borde/flecha dorados. */
.sequence-flow--light{ color:var(--cream); }
.sequence-flow--light .arrow{ color:var(--gold-light); }
.tag-list--light span{ border-color:rgba(247,251,240,.4); color:var(--cream); }

/* ============ DE LA IDEA AL ANAQUEL — v2, tarjeta blanca flotante (ref. "Decarbonisation Journey") ============
   La foto ahora se ve casi completa (sombreado suave parejo, solo para que
   la tarjeta blanca resalte, no un scrim fuerte de un lado como la v1) y el
   texto vive en una tarjeta BLANCA flotando encima, mismo lenguaje visual
   que la tarjeta de la Sección A (.scrolly-card): esquinas redondeadas,
   sombra. Dentro, el stepper (.mini-stepper) fusiona el diseño de puntos+
   línea de Empresa "Nuestra evolución" con esta referencia — aquí es
   ESTÁTICO y los 6 puntos están siempre encendidos a la vez (pedido:
   "que todos los puntos estén cubiertos", no uno solo activo). */
.anaquel-band{
  position:relative; overflow:hidden; min-height:640px;
  display:flex; align-items:center; padding:80px 0;
}
.anaquel-band-bg{
  position:absolute; inset:0; background-size:cover; background-position:center;
}
.anaquel-band-bg::after{
  content:""; position:absolute; inset:0; background:rgba(6,21,15,.22);
}
.anaquel-band .container{ position:relative; z-index:1; }
.anaquel-card{
  max-width:900px; background:var(--white); border-radius:0 28px 0 0;
  box-shadow:0 30px 64px rgba(6,21,15,.35);
  padding:clamp(32px,3.6vw,56px);
}
.anaquel-card h2{ font-size:clamp(28px,2.2vw,38px); margin-bottom:8px; }
.anaquel-card-cols{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(24px,3vw,44px); margin-top:28px; }
.anaquel-card-cols p{ font-size:18px; font-weight:500; color:var(--ink-soft); }
.anaquel-card-cols .tag-list{ margin-top:16px; }

/* ---- Mini-stepper estático: puntos + línea, todos "encendidos" a la vez
   (fusiona .timeline-flow de Empresa con la referencia de tarjeta blanca).
   Sin botones ni clic — es un adorno informativo, no interactivo. */
.mini-stepper{ display:flex; flex-wrap:wrap; position:relative; margin-top:22px; padding-top:10px; }
.mini-stepper::before{
  content:""; position:absolute; top:16px; left:0; right:0; height:2px; background:var(--cream-2);
}
.mini-stepper-item{ position:relative; flex:1 1 0; min-width:88px; display:flex; flex-direction:column; align-items:center; gap:10px; text-align:center; padding:0 4px; }
.mini-stepper-dot{ width:12px; height:12px; border-radius:50%; background:var(--cream); border:2px solid var(--cream-2); z-index:1; }
.mini-stepper-item span:last-child{ font-size:14.5px; font-weight:800; color:var(--ink-soft); }
.mini-stepper--lit::before{ background:linear-gradient(90deg, var(--terracotta), var(--gold-light)); }
.mini-stepper--lit .mini-stepper-dot{ background:var(--gold); border-color:var(--gold); }
.mini-stepper--lit .mini-stepper-item span:last-child{ color:var(--espresso); }

@media (max-width:760px){
  .anaquel-card-cols{ grid-template-columns:1fr; }
  .mini-stepper{ flex-wrap:wrap; row-gap:20px; }
  .mini-stepper-item{ flex:1 1 30%; }
  .mini-stepper::before{ display:none; }
}
@media (max-width:640px){
  .anaquel-band{ min-height:auto; padding:64px 0; }
}

/* ============ MAPA DE RED GLOBAL ============
   Réplica en SVG/CSS puro (sin librerías ni build) del efecto "world map con
   líneas que conectan puntos": fondo NEGRO (a propósito distinto del espresso
   de la banda de arriba — antes eran el mismo color y las dos secciones se
   veían como una sola masa) con los puntos recortados sobre la silueta real
   del mundo (mask-image con un mapa mudo de dominio público de Wikimedia
   Commons, licencia libre) — ya no son puntos flotando en cuadrícula, son
   puntos DENTRO de los continentes. Curvas que se van "dibujando" al hacer
   scroll (reusa .reveal/.reveal.in) y marcadores con pulso vía <animate>
   nativo de SVG. Coordenadas calculadas con proyección equirectangular
   (x=(lng+180)*k, y=(90-lat)*k) ajustada a la proporción real de ese mapa
   (899:500), para que cada punto caiga exactamente sobre su país. */
/* margin-bottom: esta sección (negra) es la única que en empresa.html
   queda justo antes de .contact-band (espresso) — dos fondos oscuros
   pegados con solo la curva de la firma entre ellos casi no se leían como
   secciones separadas (el corte se notaba, pero no había "división" real,
   a diferencia de otras páginas donde antes del contacto hay una sección
   clara/crema que sí genera contraste con la curva). Este margen deja ver
   el crema de fondo de la página antes de que empiece la curva oscura del
   bloque de contacto — la misma "pequeña división" que ya existe en el
   resto de las páginas, solo que ahí sale gratis por el color de la
   sección anterior. */
.world-map-band{ background:var(--espresso); padding:clamp(44px,4vw,72px) 0; margin-bottom:40px; color:var(--cream); }
/* Layout con botones de región: sidebar izquierda + división + mapa. El
   mapa en sí (puntos, líneas, fondo de puntos) no se toca — solo se agrega
   este marco alrededor. */
/* max-width: el contenedor del sitio llega a 1600px — a ese ancho el mapa se
   veía desproporcionadamente grande/estirado comparado con la referencia.
   Centrado y limitado a un ancho fijo se ve más compacto y "diseñado". */
.world-map-layout{ display:flex; align-items:stretch; gap:clamp(16px,1.33vw,24px); margin:clamp(32px,2.56vw,46px) auto 0; max-width:1080px; }
/* .map-sidebar siempre contiene UNO de los dos: la lista de botones (uno por
   país, salvo Latinoamérica/Asia que agrupan varios) o la tarjeta del país
   activo — nunca ambos a la vez, así la tarjeta no flota encima del mapa
   "robando" espacio, ocupa el mismo lugar que los botones. */
.map-sidebar{ flex:0 0 208px; display:flex; flex-direction:column; }
.map-controls{ display:flex; flex-direction:column; gap:7px; flex:1 1 auto; }
.map-sidebar.is-region-active .map-controls{ display:none; }
/* Lista puramente informativa (2026-09-23, pedido del cliente): ya no son
   botones — sin flecha, sin cursor de mano, sin hover/estado activo. Mismo
   bloque de color sólido y tipografía que antes, sin ningún indicio de que
   se pueda interactuar con ellos. */
.map-region-item{
  display:block;
  font-family:var(--display); font-weight:800; font-size:14.4px; text-align:left;
  color:var(--region-text, var(--cream)); background:var(--region-color);
  border-radius:0 10px 0 0; padding:10px 12px; letter-spacing:.01em;
}
.map-divider{
  flex:0 0 1px; width:1px;
  background:linear-gradient(180deg, transparent, rgba(155,197,59,.4) 15%, rgba(155,197,59,.4) 85%, transparent);
}
.world-map{
  position:relative; flex:1 1 auto; min-width:0; aspect-ratio:899/500;
  border-radius:0 var(--corner,44px) 0 0; overflow:hidden; background:var(--espresso);
}
/* Envuelve el fondo gris + el svg y anima transform (translate+scale) al
   hacer zoom a un país — nunca el viewBox del svg, para que el fondo (capa
   aparte, fuera del svg) y el svg (países, líneas, puntos) se muevan
   siempre sincronizados. Transición lenta a propósito: se pidió que el
   zoom no sea instantáneo. */
.world-map-zoom{
  position:absolute; inset:0; transform-origin:0 0;
  transition:transform .9s var(--ease); will-change:transform;
}
.world-map svg{ position:absolute; inset:0; width:100%; height:100%; }
/* Silueta completa del mundo en gris sólido (.map-world, el primer <path>
   del svg) — representa "sin cobertura". Los países CON operación van
   encima como <path> de color sólido (.map-country). Antes el gris salía
   de una imagen svg externa (Wikimedia) estirada con mask-image en un div
   aparte, con su propia proyección interna — los países de colores
   quedaban corridos respecto a ese contorno gris (más notorio mientras
   más al este). Ahora las dos capas salen del mismo GeoJSON, con la misma
   fórmula, dentro del mismo svg — no se pueden desalinear entre sí. */
.map-world{ fill:rgba(168,160,148,.45); }
/* País con operación — relleno sólido, color fijo por familia de región
   (mismo criterio que los botones). is-selected (al activar su botón) le
   agrega un borde claro para distinguirlo del resto sin cambiarle el color
   (todos están coloreados siempre, no solo el activo). */
.map-country{ transition:opacity .2s; }
.map-country.is-selected{ stroke:var(--cream); stroke-width:1.4; paint-order:stroke; }
/* Rutas con "escala": en vez de que las 23 líneas salgan todas de México
   (se veía apretado, como si "partieran de puntos distintos" por lo juntas
   que quedaban las etiquetas cerca del origen), México solo conecta
   directo con Estados Unidos/Canadá/Guatemala y con 3 puntos de relevo en
   altamar (Pacífico frente a Centroamérica, Atlántico frente a
   Sudáfrica/Canarias, Índico) — de ahí salen las líneas "escala" hacia cada
   país de esa región. Así el abanico se reparte en 4 orígenes distintos del
   mapa en vez de amontonarse en uno solo, como una ruta con conexión. */
.map-line{
  fill:none; stroke:url(#mapLineGrad);
  stroke-dasharray:100; stroke-dashoffset:100;
  transition:stroke-dashoffset var(--d,1.6s) var(--ease);
}
.map-line--trunk{ stroke-width:1.8; }
.map-line--spoke{ stroke-width:1.2; opacity:.8; }
.reveal.in .map-line{ stroke-dashoffset:0; }
.map-relay{ fill:rgba(155,197,59,.55); }
/* Área de hover invisible más grande que el punto visible (r=3, difícil de
   apuntar con el mouse) — dispara el tooltip con bandera para los países
   que no tienen etiqueta fija en el mapa. */
.map-hit{ fill:transparent; cursor:pointer; }
.map-dot{ fill:var(--gold-light); }
.map-dot--hub{ fill:var(--terracotta); }
.map-pulse{ fill:var(--gold-light); opacity:.55; }
/* Placa de la etiqueta — antes era texto suelto con solo un contorno, ahora
   es una cajita con fondo y borde (foreignObject + div), igual que en la
   referencia que se quería replicar, con los colores de marca en vez del
   azul/blanco del ejemplo. Aparece con fade-in propio (transition-delay
   inline por país, calculado para que coincida con el momento en que su
   línea termina de dibujarse) en vez de estar todas visibles desde el
   inicio — así el mapa se "puebla" progresivamente en vez de saltar de
   golpe. El foreignObject usa overflow:visible (por defecto en SVG los
   foreignObject recortan su contenido si el texto es más ancho que la caja
   declarada — eso era lo que dejaba nombres largos como "Argentina" o
   "Madagascar" con aspecto cortado). */
.world-map svg foreignObject{ overflow:visible; }
.map-label-box{
  display:inline-flex; align-items:center; white-space:nowrap;
  font-family:var(--display); font-size:13.2px; font-weight:800; color:var(--cream);
  background:rgba(11,43,32,.92); border:1px solid rgba(155,197,59,.55);
  border-radius:5px; padding:4px 9px;
  opacity:0; transition:opacity .5s var(--ease);
}
.reveal.in .map-label-box{ opacity:1; }
/* Tooltip con bandera al pasar el mouse sobre un país sin etiqueta fija —
   una sola caja compartida que JS reposiciona/rellena (ver script al final
   del body), en vez de 17 tooltips individuales. */
.map-tooltip{
  position:absolute; left:0; top:0; transform:translate(-50%,-135%);
  display:flex; align-items:center; gap:7px;
  background:rgba(11,43,32,.96); border:1px solid rgba(155,197,59,.55);
  border-radius:5px; padding:4px 9px 4px 6px;
  font-family:var(--display); font-size:12.5px; font-weight:800; color:var(--cream);
  white-space:nowrap; pointer-events:none; opacity:0; transition:opacity .15s var(--ease);
  z-index:5;
}
.map-tooltip.is-visible{ opacity:1; }
.map-tooltip-flag{ width:20px; height:14px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 1px rgba(255,255,255,.18); }
/* Tarjeta que aparece al activar un botón — misma identidad que .door (la
   tarjeta "Semillas y granos" de Proveedores): fondo blanco, foto arriba con
   la esquina curva de marca, etiqueta en mayúsculas + título abajo. Vive
   DENTRO de .map-sidebar, en el mismo lugar que ocupaban los botones (ver
   .map-sidebar.is-region-active arriba), no flota encima del mapa.
   margin:auto 0 la centra verticalmente dentro de la columna, que por
   align-items:stretch mide lo mismo que el mapa (alto). */
.map-region-card{
  display:none; flex-direction:column; position:relative;
  background:var(--white); overflow:hidden;
  border-radius:0 26px 0 0; margin:auto 0;
  box-shadow:0 20px 44px -18px rgba(0,0,0,.6);
}
.map-region-card.is-visible{ display:flex; }
.map-region-card-close{
  position:absolute; top:9px; right:9px; z-index:2;
  width:25px; height:25px; border-radius:50%;
  background:rgba(23,20,16,.55); border:none; color:var(--white); font-size:16px; line-height:1;
  cursor:pointer; display:flex; align-items:center; justify-content:center;
  opacity:.85; transition:opacity .2s, background .2s;
}
.map-region-card-close:hover{ opacity:1; background:rgba(23,20,16,.8); }
/* La "foto": bandera real (un país) o panel de color con el pin (grupo). */
.map-region-card-photo{
  aspect-ratio:4/3; overflow:hidden; background:var(--region-color, var(--gold-light));
  display:flex; align-items:center; justify-content:center;
}
.map-region-card-photo img{ width:100%; height:100%; object-fit:cover; }
.map-region-card-photo svg{ width:38px; height:38px; color:#091D15; opacity:.9; }
.map-region-card-body{ padding:16px 18px 20px; }
.map-region-card-tag{
  font-size:13.2px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
  color:var(--region-color, var(--terracotta-dark));
}
.map-region-card h3{ font-size:19px; margin:8px 0 0; font-weight:800; line-height:1.25; color:var(--espresso); }
.map-region-card-flags{
  margin-top:12px; display:flex; flex-wrap:wrap; gap:7px 9px;
  max-height:150px; overflow-y:auto;
}
.map-region-card-flag{ display:flex; align-items:center; gap:6px; font-size:12.5px; font-weight:700; color:var(--espresso); }
.map-region-card-flag img{ width:18px; height:13px; object-fit:cover; border-radius:2px; box-shadow:0 0 0 1px rgba(11,43,32,.18); flex:0 0 auto; }
.world-map-caption{ margin-top:22px; font-size:18.75px; font-weight:700; color:rgba(247,251,240,.85); }
/* Fondo negro: todo el texto de esta sección en cream/blanco, sin excepción
   (h2 y .section-head p por defecto vienen oscuros/grises, pensados para
   fondos claros). */
.world-map-band h2,
.world-map-band .section-head p,
.world-map-band .stats-head p,
.world-map-band .stat-label{ color:var(--cream); }

/* ============ RESPONSIVE ============ */
/* ============ HERO DE PORTADA EN PANTALLAS DE POCO ALTO ============
   El Hero de portada es position:fixed + height:100vh + overflow:hidden, y
   se queda así SIEMPRE — a pedido explícito del cliente, el efecto fijo
   (foto+curva quietas mientras el resto sube encima al hacer scroll) no se
   apaga bajo ninguna circunstancia, ni siquiera en pantallas cortas.
   Dos intentos anteriores apagaban el "fixed" cuando el contenido no cabía
   (mismo truco que mobile) — funcionaba contra el recorte, pero el cliente
   lo rechazó: quiere el efecto fijo intacto siempre. La solución real
   entonces es la otra mitad de la ecuación: si el contenido no cabe en
   100vh, se achica (letra, aire entre título/párrafo/botones/puntos) lo
   justo para que sí quepa — nunca se apaga el fixed, nunca se recorta nada.
   .hero y .hero-photo nunca cambian de position/height entre estados, así
   la foto/curva jamás pierde su proporción calibrada (a diferencia de los
   intentos anteriores, donde quitar el fixed alargaba la caja y deformaba
   la curva).
   El cálculo real vive en main.js (ver "Hero de portada: ajusta el tamaño
   de letra..."): mide el alto natural del bloque de texto contra el alto
   real disponible y va bajando --hero-fit (1 = tamaño normal, más chico
   según haga falta) hasta que cabe. Aquí solo se declaran las propiedades
   que main.js multiplica por esa variable. */
.hero{ --hero-fit:1; }
.hero h1{ margin-bottom:calc(26px * var(--hero-fit)); }
.hero p{ font-size:calc(19.5px * var(--hero-fit)); }
.hero-actions{ padding-top:calc(34px * var(--hero-fit)); }
.hero-dots{ margin-top:calc(44px * var(--hero-fit)); }

/* ============ HERO DE PÁGINA INTERIOR — se apila completo desde aquí ============
   2026-09-24: antes el Hero de página interior (`.page-hero`, foto con curva
   diagonal + texto a la derecha) se quedaba con la curva hasta 860px, y solo
   los botones rompían a columna un poco antes (1080px) — eso dejaba un
   rango angosto (861-1080px, y aún peor, 1081-1150px) donde el título
   quedaba muy cerca de la curva y requería ir afinando el max-width en
   varios tramos de píxeles cada vez que se reportaba un nuevo caso (ver
   historial de `#hero-oportunidades h1` más abajo). El cliente pidió, en
   vez de seguir afinando esos tramos, adelantar el punto en el que la
   sección pasa a la versión de una sola columna (foto arriba, texto abajo,
   sin curva) — así ese rango frágil desaparece del todo. Se sube el
   umbral de 860px a 930px SOLO para `.page-hero` (el resto del sitio —
   mapa, home hero, feature-band, etc. — sigue apilándose en su punto de
   siempre, 860px, ver más abajo). Pedido inicialmente a 1150px, luego el
   cliente lo bajó a 880px — verificado con la curva bezier real que entre
   881-930px es MATEMÁTICAMENTE IMPOSIBLE mantener el título en 2 líneas
   sin tocar la curva (o cabe en 2 líneas y toca la curva, o no la toca
   pero se parte en 3 líneas); 930px es el valor más cercano a 880px donde
   sí hay una solución de 2 líneas sin traslape (confirmado por el
   cliente). */
@media (max-width: 930px){
  .page-hero{ min-height:auto; flex-direction:column; align-items:stretch; padding-top:82px; }
  .page-hero-photo{ position:relative; inset:auto; height:240px; clip-path:none; }
  /* En el rango apilado ya no hay curva que tape nada, así que Alianzas
     vuelve al comportamiento normal (object-fit:cover, igual que cualquier
     otra página) en vez del object-fit:none de escritorio — ese truco solo
     tiene sentido mientras la curva sigue activa. */
  #hero-alianzas .page-hero-photo img{ object-fit:cover; object-position:50% 50%; }
  .page-hero-inner{ text-align:left; padding-top:32px; padding-bottom:48px; }
  .breadcrumb{ justify-content:flex-start; }
  /* --ph-fit (1 = tamaño normal): mismo mecanismo de auto-ajuste que ya
     usa el Hero de portada (--hero-fit en main.js), aplicado aquí solo en
     el rango apilado (foto arriba, texto abajo, sin position:fixed). Antes
     el h1 usaba el mismo clamp(34px,3vw,54px) que escritorio sin importar
     qué tan largo fuera el título — en un teléfono con pantalla baja, un
     título de 4-5 líneas no cabía completo antes de la primera "tijera"
     de scroll. Con --ph-fit, si el título+párrafo+botón no caben en el
     alto real de pantalla, JS lo achica lo justo (nunca cambia la foto). */
  /* max-width:none — la regla de escritorio (min(720px,52vw), pensada para
     dejar la curva de la foto libre a la izquierda) seguía activa aquí sin
     que nada la reseteara: en un celular de 375px, 52vw son ~195px, así que
     el título/párrafo envolvían en una columna angosta con medio ancho de
     pantalla vacío a la derecha sin usarse. En este rango apilado (foto
     arriba, sin curva) ya no hay nada que evitar del lado derecho, así que
     el texto puede usar el ancho completo del contenedor. */
  .page-hero h1{ margin-left:0; max-width:none; font-size:calc(clamp(28px,7.5vw,40px) * var(--ph-fit, 1)); }
  .page-hero p{ margin-left:0; max-width:none; font-size:calc(16.5px * var(--ph-fit, 1)); }
  .page-hero .hero-actions{ flex-direction:column; justify-content:flex-start; align-items:flex-start; margin-left:0; max-width:none; padding-top:calc(24px * var(--ph-fit, 1)); }
  /* #hero-oportunidades h1 tiene su propio max-width fijo (640px, sin media
     query) pensado solo para el rango de escritorio con curva — por
     especificidad (id) le gana a la regla de arriba y quedaba con el mismo
     problema en Oportunidades. Se resetea aquí también. */
  #hero-oportunidades h1{ max-width:none; }
}
@media (max-width: 1080px){
  /* Antes saltaba directo de 3 a 1 columna — con una tarjeta de foto (aspect-
     ratio 4:3) a todo el ancho del contenedor, la foto se volvía enorme
     (hasta ~900px de alto). Con un paso intermedio de 2 columnas, la foto
     nunca llega a ocupar tanto. */
  .doors-grid{ grid-template-columns:repeat(2,1fr); }
  /* .cats-grid y .reveal-cards YA usan auto-fit/minmax (ver sus reglas base)
     — forzarlas aquí a 1 columna las hacía saltar de golpe de 3 a 1 en vez
     de ir bajando de a poco (3→2→1) por sí solas según el espacio real
     disponible. Se quita el forzado; auto-fit ya resuelve esto sin
     necesitar ningún breakpoint manual. */
  .services-grid{ grid-template-columns:1fr; }
  .feature-grid{ grid-template-columns:1fr; gap:26px; }
  /* El overlay (título+botón+puntos) sigue sobre la foto (position:absolute,
     igual que en escritorio) — el cliente prefiere el texto siempre sobre la
     foto en vez de sacarlo. .feature-grid ya pasa a 1 columna aquí (más alto
     que en 2 columnas), así que la foto crece a 640px para darle margen de
     sobra, verificado con el mensaje más largo. El text-shadow (pensado para
     el fondo con foto de escritorio) se quita aquí: reportado que se veía
     como un sombreado sucio detrás de las letras en este rango — en
     escritorio se deja intacto, ahí sí se ve bien. */
  .feature-photo{ height:640px; }
  .feature-main h2, .feature-point h4, .feature-point p{ text-shadow:none; }
  /* Sin hover confiable en táctil: el color y el párrafo se quedan siempre
     visibles en vez de depender de pasar el mouse (que en un celular no
     existe). */
  .reveal-card-wipe{ transform:translateY(0); }
  .reveal-card-p-wrap{ max-height:160px; }
  .reveal-card-body p{ opacity:1; }
  /* .statement-grid ya NO se apila aquí (ver más abajo, se movió a un
     breakpoint más angosto) — se quita el font-size que quedó huérfano de
     un diseño anterior (esta sección usa <svg>, no texto para el ícono). */
  .footer-top{ grid-template-columns:1fr 1fr; }
  .reasons-grid{ grid-template-columns:repeat(2,1fr); }
  .standards-grid{ grid-template-columns:1fr; gap:32px; }
  .form-grid{ grid-template-columns:1fr; gap:40px; }
}
/* ============ MENÚ HAMBURGUESA UN POCO ANTES QUE EL RESTO DEL SITIO ============
   Aunque el texto del menú (.main-nav a) y el CTA del header ya son
   responsivos (clamp con vw, ver arriba), logo + 7 links + botón CTA en una
   sola fila simplemente no caben en el rango 861–~960px de ancho — ni
   siquiera en su tamaño de letra más chico permitido (12.5px, ya al límite
   de lo legible). Reportado: en ese rango angosto el header se ve apretado
   o se corta. La solución no es achicar más la letra (ya no hay margen sin
   volverse ilegible): es pasar al menú de hamburguesa (ya construido para
   mobile, ver @media max-width:860px más abajo) un poco antes de lo que
   antes forzaba el layout de una sola columna del resto del sitio — el
   header cambia a hamburguesa en 960px, el resto del sitio (grids, mapa,
   etc.) se sigue quedando en modo escritorio hasta 860px como siempre. */
@media (max-width: 960px){
  .nav-toggle{ display:flex; position:relative; z-index:2; }
  .header-right .btn-ghost{ display:none; }
  .main-nav{
    display:flex; position:fixed; top:82px; left:0; right:0; bottom:0; z-index:90;
    flex-direction:column; align-items:stretch; gap:0;
    background:var(--white);
    padding:8px 24px 24px; overflow-y:auto;
    translate:0 -14px; opacity:0; visibility:hidden; pointer-events:none;
    transition:translate .4s var(--ease), opacity .3s ease, visibility 0s linear .4s;
  }
  .main-nav.open{
    translate:none; opacity:1; visibility:visible; pointer-events:auto;
    transition:translate .4s var(--ease), opacity .35s ease, visibility 0s linear 0s;
  }
  .main-nav a{ color:var(--espresso) !important; padding:15px 4px; border-bottom:1px solid var(--line); font-size:16.5px; }
  .main-nav a::after{ display:none; }
  .main-nav a[aria-current="page"]{ color:var(--terracotta-dark) !important; font-weight:800; }
  .main-nav .mega-menu{ display:none; }
}
@media (max-width: 860px){
  /* nav-toggle / header-right .btn-ghost / .main-nav / .mega-menu ya se
     resolvieron arriba en 960px — de 861 a 860 no hay nada nuevo que hacer
     ahí, así que no se repiten aquí. */

  /* "Conectamos orígenes globales" (ícono de montañas + texto): antes se
     apilaba (1 columna) desde 1080px — a pedido del cliente, se queda en 2
     columnas más tiempo (el ícono ya se achica solo con el ancho, clamp en
     .statement-graphic svg) y solo pasa a apilarse aquí, en el mismo punto
     donde el resto del sitio ya considera "mobile". */
  .statement-grid{ grid-template-columns:1fr; }
  .statement-graphic{ min-height:200px; justify-content:center; }
  /* Reportado que el bloque apilado se veía descuadrado (ícono e h2 pegados
     a la izquierda, sueltos) — centrado, como cualquier bloque de una sola
     columna con un ícono arriba y texto abajo. */
  .statement-text{ text-align:center; }
  .statement-text h2{ max-width:20ch; margin-left:auto; margin-right:auto; }
  .statement-text p{ max-width:52ch; margin-left:auto; margin-right:auto; }

  /* Sidebar de botones de región: en mobile no cabe angosta a la izquierda,
     se convierte en una fila horizontal arriba del mapa (una de las 3
     ubicaciones pedidas). */
  .world-map-layout{ flex-direction:column; gap:0; }
  .map-sidebar{ flex:0 0 auto; width:100%; }
  .map-controls{ flex:0 0 auto; flex-direction:row; flex-wrap:wrap; gap:8px; width:100%; }
  .map-region-item{ flex:1 1 auto; min-width:110px; padding:9px 10px; font-size:14.4px; }
  .map-divider{ width:100%; height:1px; margin:18px 0; flex-basis:1px;
    background:linear-gradient(90deg, transparent, rgba(155,197,59,.4) 15%, rgba(155,197,59,.4) 85%, transparent); }
  .map-region-card{ width:100%; margin:0; }

  /* ---- Barra utilitaria (Contacto/Ubicaciones/Buscar/idioma/Portal
     proveedores): en mobile no cabe bien arriba y se veía mal — se oculta
     por completo de aquí y su contenido se repite dentro del menú de
     hamburguesa (.mobile-nav-extra, más abajo), que ahora ocupa toda la
     pantalla. ---- */
  .util-bar{ display:none; }

  /* ---- Contenido de la barra utilitaria, repetido aquí para mobile ---- */
  .mobile-nav-extra{ display:flex; flex-direction:column; gap:2px; margin-top:14px; padding-top:14px; border-top:1px solid var(--line); }
  .mobile-nav-extra a, .mobile-nav-extra button{
    display:flex; align-items:center; gap:10px; padding:13px 4px;
    color:var(--espresso); font-size:15.5px; font-weight:600;
  }
  .mobile-nav-extra svg{ width:18px; height:18px; flex:0 0 auto; color:var(--ink-soft); }
  .mobile-lang{ display:flex; align-items:center; gap:4px; padding:8px 4px; }
  .mobile-lang button{ padding:4px 8px; font-weight:700; color:var(--ink-soft); }
  .mobile-lang button.active{ color:var(--terracotta-dark); }
  .mobile-lang span{ color:var(--line-strong); }
  .mobile-lang .lang-flag{ box-shadow:0 0 0 1px rgba(11,43,32,.18); }
  .mobile-nav-extra .util-subscribe{
    margin-top:8px; background:var(--terracotta); color:var(--cream);
    justify-content:center; border-radius:4px; font-weight:800;
  }

  /* ---- Header transparente-sobre-foto: bug real en mobile. Ese esquema
     (logo/texto color crema, fondo transparente) asume que el header queda
     FLOTANDO sobre la foto del hero (position:fixed, como en escritorio). En
     mobile el hero ya no es fixed — la foto queda en el flujo normal, DEBAJO
     del header, así que el header transparente terminaba mostrando texto
     crema sobre fondo crema: invisible. Aquí se fuerza siempre la versión
     sólida/oscura (la misma que usa el estado "scrolled"), sin importar si
     hiciste scroll o no. ---- */
  body.home .site-header{ background:var(--espresso); }
  body.home .site-header::before{ display:none; }
  body.home .site-header .brand-word{ color:var(--cream); }
  body.home .site-header .brand-mark{ filter:none; }
  body.home .site-header .nav-toggle{ border-color:rgba(247,251,240,.4); color:var(--cream); }

  /* El "pinned hero" se apaga en mobile — vuelve a fluir normal, sin fixed. */
  /* body.home .hero{padding-top:82px} le gana a .hero{padding-top:20px} por
     especificidad si no repetimos el mismo prefijo aquí — quedaba un hueco
     naranja de más arriba del que debía en mobile. */
  body.home .hero{ position:relative; top:auto; min-height:auto; padding-top:20px; flex-direction:column; align-items:stretch; height:auto; }
  .hero-spacer{ display:none; }
  .hero-photo{ position:relative; inset:auto; height:280px; clip-path:none; margin:0 -32px 28px; }
  /* La máscara que pinta la curva (ver nota grande en .hero-photo-mask,
     arriba) es un elemento aparte de .hero-photo, así que la regla de
     arriba (clip-path:none) no la toca — sin esto, la curva se seguía
     viendo encima de la foto en mobile aunque .hero-photo ya la hubiera
     "apagado". En mobile la foto va completa, sin ningún recorte ni forma
     encima, igual que .hero-photo-photo (interior) en su propio breakpoint. */
  .hero-photo-mask{ display:none; }
  /* En mobile .hero-slide-wrap pierde su max-width (línea de abajo) para
     que el texto pueda ocupar el ancho completo — con .container ya
     aportando su padding responsive esto no haría falta, pero se deja un
     valor propio (más angosto que el de .container en este ancho) porque
     aquí el texto es mucho más grande y necesita más aire que el resto del
     sitio. */
  .hero-inner{ padding-left:32px; padding-right:32px; }
  .hero-slide-wrap{ max-width:none; text-align:left; }
  /* El piso del clamp() (41px) venía pensado para una caja más ancha — en un
     teléfono chico esa letra tan gruesa llenaba casi todo el renglón antes
     de partir línea, y la última palabra terminaba pegada al margen. Un
     poco más chica en mobile deja más aire a la derecha. */
  .hero h1{ font-size:clamp(32px, 9vw, 46px); }
  /* .hero-slide es flex-column con align-items:flex-start (no "stretch"),
     así que sus hijos NO se estiran al ancho del contenedor — cada uno toma
     el ancho que prefiera su propio contenido. El párrafo tiene
     max-width:46ch pensado para escritorio (una caja angosta y legible); en
     mobile, sin "stretch", esa caja de 46ch podía ser MÁS ANCHA que la
     pantalla y se salía por la derecha en vez de encogerse. */
  .hero-slide{ align-items:flex-start; }
  .hero p{ margin-left:0; max-width:none; width:100%; }
  .hero-actions{ justify-content:flex-start; }

  /* ---- "Conozca más sobre VOLT" (feature-band): el texto va superpuesto a
     la foto con position:absolute a una altura fija (620px en escritorio) —
     en mobile la foto es más baja y el texto (título largo + botón + 2
     puntos) no cabe ahí, así que se derramaba fuera de esa altura y se
     encimaba visualmente con la sección de Contacto que sigue. Se apila
     normal (foto arriba, texto abajo en flujo), en vez de superpuesto. ---- */
  .feature-photo{ height:300px; }
  .feature-photo::after{ display:none; }
  .feature-overlay{ position:static; padding:28px 0 0; }
  .feature-main h2{ color:var(--espresso); max-width:none; }
  .feature-main .accent-word{ color:var(--terracotta); }
  /* .btn-pill es crema-sobre-oscuro (pensado para ir encima de la foto) — al
     apilar el texto en fondo claro se volvía invisible (crema sobre crema). */
  .feature-main .btn-pill{ background:var(--espresso); color:var(--cream); }
  .feature-main .btn-pill:hover{ background:var(--terracotta); color:var(--cream); }
  .feature-point h4{ color:var(--terracotta-dark); }
  .feature-point p{ color:var(--ink-soft); }

  /* ---- Hero de página interior: mismo bug que tuvo el hero del home en
     mobile — la foto va con clip-path en diagonal cubriendo TODA la sección
     como fondo absoluto, pensado para convivir con texto a la derecha sobre
     mucho espacio vacío. En mobile no hay espacio vacío: el texto ocupa
     todo el ancho y termina encimado sobre la foto, casi ilegible. Mismo
     arreglo que allá: la foto se apila arriba (bloque propio, sin recorte),
     el texto va abajo en flujo normal, alineados a la izquierda. ---- */
  /* Reglas de `.page-hero` (foto/texto/botones) movidas a @media 1150px más
     arriba — aquí solo queda lo que sigue dependiendo del punto "sin barra
     de utilidad" (82px de header en vez de 134px). */
  .reasons, .doors, .standards, .steps, .form-section, .world-map-band, .services, .diag-split{ scroll-margin-top:82px; }

  .reasons-grid{ grid-template-columns:1fr; gap:30px; }
  .prequal-form{ grid-template-columns:1fr; }

  /* Línea de tiempo, riel de proceso y riel vertical: en desktop dependen
     de espacio horizontal para la línea conectora; en mobile se apilan en
     columna con la línea a la izquierda en vez de arriba. */
  .timeline-flow{ flex-direction:column; gap:22px; }
  .timeline-flow::before{ top:0; bottom:0; left:5px; right:auto; width:1.5px; height:auto; background:linear-gradient(180deg, var(--terracotta), var(--gold-light)); }
  .timeline-point{ flex-direction:row; text-align:left; align-items:center; padding:0; gap:14px; }
  .timeline-detail{ grid-template-columns:1fr; gap:22px; }
  .timeline-detail-photo{ order:-1; }
  .evolution-card{ padding:36px 24px 40px; border-radius:26px; max-width:600px; }
  .evolution-card .timeline-detail{ grid-template-columns:1fr; gap:20px; margin-top:30px; }
  .evolution-card .timeline-detail-photo{ height:200px; }
  /* En mobile la línea de tiempo se apila en columna con los números
     pegados al borde izquierdo — las flechas ya no caben flotando sobre
     los bordes del borde sin encimarse con el punto 1, así que se agrupan
     arriba a la derecha, lejos de esa columna. */
  .timeline-nav-arrow{ width:38px; height:38px; }
  .timeline-nav-arrow--prev{ left:auto; right:56px; top:16px; transform:none; }
  .timeline-nav-arrow--next{ right:12px; top:16px; transform:none; }
  .timeline-nav-arrow:hover{ transform:scale(1.06); }

  .process-rail{ flex-direction:column; gap:34px; }
  .rail-step{ text-align:left; display:flex; align-items:flex-start; padding:0; }
  .rail-step:not(:last-child)::after{ display:none; }
  .rail-ico{ margin:0 18px 0 0; flex-shrink:0; }

  .rail-vertical::before{ left:16px; }
  .rail-vertical-item{ width:100%; margin-left:0 !important; margin-right:0 !important; text-align:left !important; padding-left:48px; }
  .rail-vertical-item:nth-child(odd) .rail-vertical-num,
  .rail-vertical-item:nth-child(even) .rail-vertical-num{ left:0; right:auto; }

  .arrow-steps{ flex-direction:column; align-items:flex-start; gap:20px; }
  .arrow-steps-sep{ display:none; }

  .photo-band-row{ padding:24px; align-items:flex-start; }
}
@media (max-width: 600px){
  .container{ padding:0 20px; }
  .hero-inner{ padding-left:28px; padding-right:28px; }
  .util-bar-inner{ height:auto; padding:8px 0; flex-wrap:wrap; gap:8px; }
  .footer-top{ grid-template-columns:1fr; }
  .feature-band{ margin-bottom:90px; }
  .services{ padding:64px 0; }
  .doors{ padding:64px 0; }
  .contact-band{ padding:70px 20px 80px; }
  .reasons{ padding:64px 0; }
  .standards{ padding:56px 0; }
  .form-section{ padding:64px 0; }
  .steps{ padding:64px 0; }
  .evolution-card{ padding:32px 18px 36px; }
  .world-map-band{ padding:64px 0; }
  .map-label-box{ font-size:12.6px; padding:3.5px 8px; }
  .map-region-item{ min-width:0; font-size:13.2px; padding:8px 8px; }
  .map-region-card-body{ padding:14px 16px 18px; }
}

/* ============ BUSCADOR DEL SITIO ============
   Modal centrado, sin dependencias — se inyecta una sola vez desde i18n.js
   (buildSearchModal) y queda oculto (opacity/visibility) hasta que algún
   botón .js-search-open lo abre. Mismo lenguaje visual que el resto del
   sitio (radius, sombra, paleta espresso/crema) en vez de un <input>
   nativo suelto. */
.search-overlay{
  position:fixed; inset:0; z-index:300;
  background:rgba(11,43,32,.55);
  display:flex; align-items:flex-start; justify-content:center;
  padding:14vh 20px 20px;
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .2s ease;
}
.search-overlay.is-visible{ opacity:1; visibility:visible; pointer-events:auto; }
body.search-open{ overflow:hidden; }
.search-box{
  width:100%; max-width:560px; background:var(--white); border-radius:var(--radius);
  box-shadow:0 30px 70px rgba(6,21,15,.35);
  overflow:hidden;
  transform:translateY(-8px); transition:transform .2s ease;
}
.search-overlay.is-visible .search-box{ transform:translateY(0); }
.search-box-top{ display:flex; align-items:center; gap:12px; padding:18px 20px; border-bottom:1px solid var(--line); }
.search-box-top svg{ width:20px; height:20px; color:var(--ink-soft); flex:0 0 auto; }
.search-input{ flex:1; border:0; outline:0; font-family:inherit; font-size:17px; color:var(--ink); background:none; }
.search-input::placeholder{ color:var(--ink-soft); }
.search-close{
  width:28px; height:28px; border-radius:50%; border:0; background:var(--cream);
  color:var(--ink-soft); font-size:18px; line-height:1; cursor:pointer; flex:0 0 auto;
}
.search-close:hover{ background:var(--line); }
.search-results{ max-height:50vh; overflow-y:auto; padding:8px; }
.search-result{
  display:block; padding:13px 14px; border-radius:8px; font-weight:700; color:var(--ink);
  transition:background .15s;
}
.search-result:hover{ background:var(--cream); color:var(--terracotta-dark); }
.search-empty{ padding:16px 14px; color:var(--ink-soft); font-size:18.1px; }
.search-suggestions-label{ padding:10px 14px 4px; color:var(--ink-soft); font-size:12.5px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; }

/* ============ BOTÓN "VOLVER ARRIBA" ============
   Mismo lenguaje visual que el resto del sitio en vez de un círculo
   genérico: la esquina "cortada" (border-radius asimétrico) que ya usan
   las tarjetas .door/.reason-card, espresso+dorado como .btn-dark, y la
   MISMA flecha de los CTA (.btn-pill/.btn-text) girada 90° hacia arriba
   en vez de un ícono de flecha distinto. */
.back-to-top{
  position:fixed; right:28px; bottom:28px; z-index:250;
  width:52px; height:52px; border-radius:16px 16px 4px 16px;
  background:var(--espresso); color:var(--gold-light);
  border:1px solid rgba(155,197,59,.3);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 16px 32px rgba(6,21,15,.3);
  cursor:pointer;
  opacity:0; visibility:hidden; transform:translateY(14px) scale(.9);
  transition:opacity .3s var(--ease), transform .3s var(--ease), visibility 0s linear .3s, background .25s, border-radius .3s var(--ease);
}
.back-to-top.is-visible{
  opacity:1; visibility:visible; transform:translateY(0) scale(1);
  transition:opacity .3s var(--ease), transform .3s var(--ease), background .25s, border-radius .3s var(--ease);
}
.back-to-top:hover{ background:var(--terracotta); border-radius:22px 22px 4px 22px; }
.back-to-top svg{ width:20px; height:20px; }
@media (max-width:860px){
  .back-to-top{ right:16px; bottom:16px; width:46px; height:46px; }
  .back-to-top svg{ width:18px; height:18px; }
}

/* ============ SECCIÓN A — scroll fijo con puntos (referencia Olam Agri, "Rice Certification") ============
   Precisión del video de referencia (revisado fotograma a fotograma):
   - La FOTO NUNCA CAMBIA — es una sola imagen fija durante todo el recorrido.
   - Una tarjeta blanca de esquinas redondeadas flota ENCIMA de la foto (no
     al lado, en columna separada) con el texto de cada paso.
   - El texto hace CROSSFADE entre pasos (se funden uno sobre otro), no
     desliza ni cambia de posición.
   - Los puntos viven en un riel pegado al borde IZQUIERDO de toda la
     sección, fuera de la foto — no junto al texto.
   .scrolly-scene da la altura de scroll (3 x 92vh) y contiene el bloque
   sticky (foto+tarjeta) más 3 "gatillos" invisibles que main.js observa
   con IntersectionObserver para saber qué paso está activo. */
/* Se probó el título fijo (sticky) junto a la foto (ver historial), pero el
   cliente reportó un glitch: al terminar el scroll, la caja crema de fondo
   del título se quedaba flotando encima de la SIGUIENTE sección como un
   rectángulo suelto y desconectado. Pidió explícitamente que el título NO
   necesita acompañar todo el scroll — vuelve a ser un encabezado normal
   (estático), solo la foto+tarjeta+riel quedan fijos. */
.scrolly-grid{ margin-top:8px; }
/* Separación clara con la sección siguiente — antes quedaban pegadas y
   parecía que una "se comía" un pedazo de la otra al terminar el scroll. */
.scrolly{ margin-bottom:56px; }
/* Riel de puntos: ahora vive DENTRO de .scrolly-pin (columna propia del
   grid, junto a la foto), no como elemento aparte con su propio sticky —
   pedido del cliente: "no quiero que se muevan conforme vayamos
   escroleando, deben quedar fijos junto a la sección". Al ser columna del
   mismo bloque sticky que la foto, se mueve exactamente igual que ella, ni
   un pixel de más ni de menos; centrado dentro de la altura del bloque
   (align-self:center), no de la ventana. */
.scrolly-rail{
  grid-column:1; grid-row:1; align-self:center; justify-self:center;
  display:flex; flex-direction:column; align-items:center; justify-content:space-between;
  height:180px; position:relative;
}
.scrolly-rail::before, .scrolly-rail::after{
  content:''; position:absolute; left:50%; translate:-50% 0; width:2px; top:8px; bottom:8px;
}
.scrolly-rail::before{ background:var(--cream-2); }
/* Bug: --progress es un % del alto TOTAL del riel (180px), pero la línea
   solo ocupa 164px reales (180 − 8px arriba − 8px abajo) — al llegar al
   último punto (progress:100%) la barra medía 180px completos y se salía
   8px por debajo del último punto, dejando ese "rabito" visible que
   reportó el cliente. Con calc() se limita al tramo real entre puntos. */
.scrolly-rail::after{ background:var(--gold); bottom:auto; height:calc(var(--progress,0) * (100% - 16px)); transition:height .6s var(--ease); }
.scrolly-dot{
  width:16px; height:16px; border-radius:50%; background:var(--cream); border:2.5px solid var(--cream-2);
  transition:background .4s var(--ease), border-color .4s var(--ease), transform .4s var(--ease), box-shadow .4s var(--ease);
  position:relative; z-index:1; flex:0 0 auto;
}
.scrolly-dot.passed{ background:var(--gold); border-color:var(--gold); }
.scrolly-dot.active{ transform:scale(1.3); box-shadow:0 0 0 5px color-mix(in srgb, var(--gold) 25%, transparent); }

.scrolly-scene{ position:relative; }
/* top más alto a propósito: pedido del cliente — quiere que el fijado
   "enganche" más tarde, dejando ver el título "Lo que VOLT ofrece" arriba
   de la foto un momento más (como en su captura de referencia) en vez de
   que la foto quede pegada al header casi de inmediato. */
.scrolly-pin{
  position:sticky; top:200px;
  display:grid; grid-template-columns:40px 1fr; column-gap:clamp(16px,2.4vw,32px); height:64vh;
}
.scrolly-photo{ grid-column:2; grid-row:1; height:100%; border-radius:0 56px 0 0; overflow:hidden; box-shadow:0 26px 48px rgba(11,43,32,.18); }
.scrolly-photo img{ width:100%; height:100%; object-fit:cover; display:block; }
/* Esquinas: identidad de marca del sitio es UNA sola esquina curva (arriba-
   derecha), como .door/.reason-card — no las 4 redondeadas parejo, que el
   cliente marcó como error de consistencia visual. */
.scrolly-card{
  grid-column:2; grid-row:1; align-self:end; justify-self:end;
  width:min(52%,560px); margin:0 clamp(16px,3vw,40px) clamp(-32px,-3vw,-16px) 0;
  background:var(--white); border-radius:0 28px 0 0; overflow:hidden;
  box-shadow:0 30px 56px rgba(11,43,32,.2);
  position:relative; min-height:300px;
}
/* Efecto pedido: "que se vea una tarjeta saliendo por debajo de otra" — no
   un simple fundido de opacidad. Cada paso vive apilado (position:absolute,
   siempre, nunca cambia a relative) DENTRO de .scrolly-card, que tiene
   overflow:hidden para recortar el que está fuera. El paso inactivo se
   guarda 100% más abajo (translateY(100%)); al activarse sube a su lugar
   (translateY(0)) tapando al anterior, que baja y desaparece al mismo
   tiempo — de ahí la sensación de una tarjeta emergiendo por debajo de la
   otra. Transición lenta (1.3s) con curva "ease-out" pronunciada para que
   se sienta fluida, no espontánea. */
.scrolly-step{
  grid-area:1/1; position:absolute; inset:0; padding:clamp(28px,3vw,44px);
  opacity:0; transform:translateY(100%);
  transition:transform 1.3s cubic-bezier(.16,1,.3,1), opacity 1.1s ease;
  pointer-events:none;
}
.scrolly-step.active{
  opacity:1; transform:translateY(0); pointer-events:auto;
  transition:transform 1.3s cubic-bezier(.16,1,.3,1), opacity .9s ease;
}
.scrolly-step h3{ font-size:clamp(24px,2vw,32px); margin:0 0 14px; font-weight:800; line-height:1.2; color:var(--espresso); }
.scrolly-step p{ font-size:17px; font-weight:500; color:var(--ink-soft); }

/* Scroll más corto entre pasos: pedido explícito del cliente ("el scroll se
   tarda mucho, un punto a otro más corto") — antes eran 92vh por paso. El
   último trigger es más alto a propósito: da tiempo de sobra para que la
   animación de 1.3s de la tarjeta termine ANTES de que .scrolly-pin se
   despegue (deje de ser sticky) y aparezca la siguiente sección — si es
   muy corto, el scroll llega al final del bloque a media animación y la
   siguiente sección se monta encima ("se come" la tarjeta a medio subir). */
/* Los 3 pasos + la salida deben tardar lo MISMO en scroll — pedido
   explícito del cliente, dio "7/3/1/casi nada" como referencia de lo mal
   parejo que se sentía y pidió que las 4 fueran iguales (usando "5" como
   unidad relativa). .scrolly-trigger controla cuánto dura cada paso en
   pantalla; .scrolly-exit-space es un espaciador aparte (no tiene
   data-step, no lo observa el JS) que da el mismo tiempo de "salida" antes
   de que aparezca la siguiente sección, en vez de que el bloque se suelte
   casi de inmediato después del tercer paso. */
.scrolly-trigger{ height:55vh; }
.scrolly-exit-space{ height:55vh; }

@media (max-width:900px){
  /* Sin scroll fijo en móvil (no hay espacio ni sentido para el efecto):
     la foto se muestra una sola vez arriba y los 3 pasos se listan debajo,
     apilados, todos visibles — nada que activar con JS aquí. */
  .scrolly-rail{ display:none; }
  .scrolly-scene{ height:auto !important; }
  .scrolly-pin{ position:static; height:auto; display:block; }
  .scrolly-photo{ height:auto; aspect-ratio:4/3; border-radius:0 40px 0 0; }
  .scrolly-card{ position:static; width:auto; margin:0; border-radius:0; box-shadow:none; padding:0; background:none; }
  .scrolly-step{ position:static; opacity:1; transform:none; padding:26px 0; border-bottom:1px solid var(--cream-2); }
  .scrolly-step:last-child{ border-bottom:none; }
  /* Apilado: el `justify-self:end` del diseño de escritorio seguía aplicando y pegaba el bloque de
     texto a la derecha con un hueco a la izquierda. Aquí va alineado con la foto (izquierda), con un
     ancho máximo para que las líneas no queden demasiado largas en tabletas. */
  .scrolly-card{ justify-self:start; max-width:640px; }
  .scrolly-trigger{ display:none; }
  .scrolly-exit-space{ display:none; }
}

/* ============ SECCIÓN F — tarjetas oscuras apiladas con scroll (sticky) ============
   2026-09-24. Referencia real: video `Grabación de pantalla 2026-09-23
   052935.mp4` (Olam Agri "About Us", tarjetas "Building on Our Heritage" /
   "A New Chapter of Growth") — se extrajeron fotogramas para analizarlo
   fotograma a fotograma (no se puede reproducir video directamente en este
   entorno). Confirmado: NO es solo un escalonado visual estático (esa fue
   la primera versión, incorrecta) — es un efecto real ligado al scroll:
   la tarjeta 1 se queda FIJA en pantalla (`position:sticky`) mientras la
   tarjeta 2 sube por detrás/debajo y la va tapando progresivamente hasta
   cubrirla del todo; el efecto es reversible (funciona igual al subir el
   scroll), típico de tarjetas sticky apiladas con z-index creciente por
   orden de aparición (la última tarjeta en el DOM tapa a todas las
   anteriores). Con la identidad de marca del sitio: UNA sola esquina
   redondeada grande (arriba-derecha en tarjetas foto-izquierda,
   arriba-izquierda en foto-derecha, para que la curva siempre quede del
   lado del texto), en vez de las 4 esquinas redondeadas del original.
   1er uso: Logística "Nuestra operación de punta a punta". */
.zigzag-list{ position:relative; }
.zigzag-card{
  position:sticky; top:96px; margin-bottom:24px;
  display:grid; grid-template-columns:1fr 1fr; align-items:stretch;
  min-height:440px;
  background:var(--espresso); color:var(--cream); overflow:hidden;
  --corner:64px; border-radius:0 var(--corner) 0 0;
  box-shadow:0 24px 48px rgba(11,43,32,.28);
}
/* z-index creciente por orden de aparición — así, al quedar todas
   "pegadas" en el mismo `top`, la que va llegando por detrás (más abajo en
   el documento) siempre se pinta ENCIMA de las anteriores, exactamente
   como en el video de referencia. */
.zigzag-card:nth-child(1){ z-index:1; }
.zigzag-card:nth-child(2){ z-index:2; }
.zigzag-card:nth-child(3){ z-index:3; }
.zigzag-card:nth-child(4){ z-index:4; }
.zigzag-card:nth-child(5){ z-index:5; }
.zigzag-photo{ position:relative; min-height:320px; }
.zigzag-photo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.zigzag-text{ padding:48px 46px; display:flex; flex-direction:column; justify-content:center; position:relative; }
/* 2026-09-24: marca de agua del logo — pedido del cliente de agregarla en
   más secciones de fondo SÓLIDO oscuro (no fotos). El lado de texto de cada
   tarjeta ya es fondo sólido espresso, así que la marca va ahí, detrás del
   título/párrafo (z-index:0), en la esquina inferior. */
.zigzag-text::after{
  content:""; position:absolute; z-index:0; pointer-events:none;
  right:6%; bottom:-6%; width:34%; aspect-ratio:372/357; min-width:120px;
  background:rgba(247,251,240,.14);
  -webkit-mask:var(--m-hojas) no-repeat center/contain;
  mask:var(--m-hojas) no-repeat center/contain;
}
.zigzag-text > *{ position:relative; z-index:1; }
.zigzag-text h3{ color:var(--gold); font-size:28px; font-weight:800; margin:0 0 16px; line-height:1.15; }
.zigzag-text h3 .accent-word{ color:var(--gold); }
/* Las etiquetas (.tag-list) usan texto espresso por defecto: sobre el fondo oscuro de la tarjeta
   quedaban invisibles y solo se notaba un hueco vacío. Aquí van en versión clara. */
.zigzag-text .tag-list span{ border-color:rgba(247,251,240,.45); color:var(--cream); }
.zigzag-text p{ font-size:17.5px; line-height:1.6; color:rgba(247,251,240,.82); margin:0; max-width:46ch; }
/* Foto a la derecha en las tarjetas pares — orden de columnas invertido
   (grid-column, no `direction`, para no romper la lectura del texto) y la
   esquina redondeada se mueve al otro lado para seguir "acompañando" el
   texto, nunca la foto. */
.zigzag-card--rev{ border-radius:var(--corner) 0 0 0; }
.zigzag-card--rev .zigzag-photo{ order:2; }
.zigzag-card--rev .zigzag-text{ order:1; }
@media (max-width:860px){
  /* El apilado sticky necesita espacio vertical de sobra para lucir (cada
     tarjeta debe verse completa antes de que la tape la siguiente) — en
     mobile, con pantallas más bajas, se apila normal en flujo (sin
     sticky) para no sentirse atorado por varias pantallas de scroll. */
  .zigzag-card{ position:static; margin-bottom:20px; min-height:auto; }
  .zigzag-card, .zigzag-card--rev{ grid-template-columns:1fr; border-radius:0 40px 0 0; }
  .zigzag-card--rev .zigzag-photo, .zigzag-card--rev .zigzag-text{ order:0; }
  .zigzag-photo{ min-height:220px; }
  .zigzag-text{ padding:32px 28px; }
}

/* ============ SECCIÓN H — carrusel foto + panel de color sólido ============
   2026-09-24, 1er uso. Referencia: video Olam Agri "Sustainability" —
   foto grande a la izquierda, panel de color SÓLIDO a la derecha (cambia
   de color por slide) con título+texto, flechas prev/next, puntos de
   paginación abajo. Versión simplificada (sin el "peek" del slide
   siguiente asomando, para no complicar el JS) — mismo espíritu: foto +
   bloque de color con el texto. Genérico, reutilizable por cualquier
   `.h-carousel` de la página (main.js lo maneja). */
.h-carousel{ position:relative; overflow:hidden; --corner:56px; border-radius:0 var(--corner) 0 0; box-shadow:0 24px 48px rgba(11,43,32,.16); }
.h-carousel-track{ display:flex; transition:transform .5s var(--ease); }
.h-carousel-slide{ flex:0 0 100%; display:grid; grid-template-columns:1fr 1fr; min-height:420px; }
.h-carousel-photo{ position:relative; }
.h-carousel-photo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.h-carousel-panel{
  background:var(--panel-color, var(--terracotta)); color:var(--cream); padding:48px 82px 48px 46px; /* 82px a la derecha = flecha (44px) + su margen (18px) + aire, para que no tape el texto */
  display:flex; flex-direction:column; justify-content:center;
  text-decoration:none; transition:filter .2s;
}
.h-carousel-panel:hover{ filter:brightness(1.06); }
/* h3/h2 tienen color:var(--espresso) global en todo el sitio (regla base
   h1,h2,h3{color:...}) — sin esto aquí, el título se pintaba SIEMPRE
   oscuro sin importar el color de fondo del panel, y sobre paneles
   oscuros (espresso, verde oscuro) quedaba invisible (letra oscura sobre
   fondo oscuro). El color heredado del contenedor NO le gana a una regla
   que apunta directo al elemento, por eso hacía falta ponerlo aquí
   explícito. */
.h-carousel-panel h3{ font-size:27px; font-weight:800; margin:0 0 16px; line-height:1.15; color:var(--cream); }
.h-carousel-panel p{ font-size:17.5px; line-height:1.6; color:rgba(255,253,248,.9); margin:0; max-width:42ch; }
.h-carousel-arrow{
  position:absolute; top:50%; translate:0 -50%; z-index:2;
  width:44px; height:44px; border-radius:50%; border:none; cursor:pointer;
  background:var(--cream); color:var(--espresso); display:flex; align-items:center; justify-content:center;
  box-shadow:0 8px 20px rgba(11,43,32,.22); transition:background .2s;
}
.h-carousel-arrow:hover{ background:var(--gold); }
.h-carousel-arrow svg{ width:18px; height:18px; }
.h-carousel-arrow--prev{ left:18px; }
.h-carousel-arrow--next{ right:18px; }
.h-carousel-dots{ position:absolute; left:50%; translate:-50% 0; bottom:18px; z-index:2; display:flex; gap:8px; }
.h-carousel-dots button{ width:9px; height:9px; border-radius:50%; border:none; padding:0; background:rgba(255,253,248,.45); cursor:pointer; transition:background .2s,transform .2s; }
.h-carousel-dots button.is-active{ background:var(--cream); transform:scale(1.25); }
@media (max-width:760px){
  .h-carousel-slide{ grid-template-columns:1fr; min-height:auto; }
  .h-carousel-photo{ min-height:200px; }
  .h-carousel-panel{ padding:32px 28px; }
  /* Apilado (foto arriba, texto abajo): las flechas centradas en TODA la altura
     caían sobre el título del panel. Se centran en la foto (200px de alto). */
  .h-carousel-arrow{ top:100px; }
}

/* ============ MARCA DE AGUA — siluetas del logo de fondo ============
   2026-09-24, pedido del cliente: en secciones con fondo oscuro sólido
   (espresso/negro, ej. .zigzag-card, .anaquel-band), agregar una marca de
   agua grande y muy tenue con la silueta de las montañas del logo VOLT
   (los mismos 2 polígonos del isotipo), como referencia de otros sitios
   que ponen una silueta decorativa de su propio ícono detrás del texto.
   Utilidad genérica: agregar la clase `.brand-marks-bg` a cualquier
   contenedor con `position:relative` y fondo oscuro — se pinta como
   ::after (encima del fondo/foto, detrás del texto si el texto tiene
   z-index:1) en la esquina inferior derecha, muy grande y a muy baja
   opacidad, sin interferir con la lectura. */
.brand-marks-bg{ position:relative; overflow:hidden; }
.brand-marks-bg::after{
  content:""; position:absolute; z-index:0; pointer-events:none;
  right:-4%; bottom:-8%; width:46%; aspect-ratio:372/357; min-width:340px;
  background:rgba(247,251,240,.16);
  -webkit-mask:var(--m-hojas) no-repeat center/contain;
  mask:var(--m-hojas) no-repeat center/contain;
}
/* Sobre .anaquel-band, la foto de fondo (.anaquel-band-bg) y la tarjeta
   (.container) son elementos hermanos posteriores en el DOM — para que la
   marca de agua quede ENCIMA de la foto (si no, quedaría tapada por
   completo) pero DETRÁS de la tarjeta de texto, se le da z-index:0 (ya
   puesto arriba) y a la tarjeta ya le toca z-index:1 vía `.container`. */

/* --solid: para fondos muy coloridos/con mucha textura (ej. foto a color de
   personas/paisaje), donde la marca de agua en .16 casi no se distinguía —
   pedido del cliente: "hay que agregarle un poco más de color blanco...
   un sólido un color un poco más sólido para que se alcance a ver mejor". */
.brand-marks-bg--solid::after{ background:rgba(255,255,255,.28); }

/* --top-left: variante de esquina opuesta, más chica, para que no todos los
   fondos oscuros del sitio se vean iguales ("no todos deben ser de un modo,
   deben ir diferentes"). */
.brand-marks-bg--top-left::after{
  right:auto; left:-3%; bottom:auto; top:-6%; width:30%; min-width:220px;
  background:rgba(247,251,240,.13);
}
/* --small: para paneles angostos (ej. un slide de `.h-carousel` con
   `--panel-color:espresso`) donde la versión grande no cabría bien. */
.brand-marks-bg--small::after{ width:34%; min-width:130px; right:-6%; bottom:-10%; }

/* ============ SECCIÓN L — "Lista + foto fija" ============
   2026-09-25: iba a ser un componente de pestañas (referencia Olam Agri
   "Proven Expertise that Meet Your Needs") pero el cliente lo simplificó
   al ver que con solo 4 pasos cortos no tenía sentido "elegir" entre 2
   grupos que de todos modos mostraban prácticamente lo mismo — ahora es
   texto fijo a la izquierda + foto fija a la derecha, sin interacción,
   con la animación de entrada `.reveal` genérica del sitio.
   1er uso: Proveedores "Cómo evaluamos nuevos proveedores". */
#como-evaluamos .section-head{ max-width:900px; }
.tab-expertise-body{
  display:grid; grid-template-columns:1fr 1fr; gap:clamp(28px,4vw,64px); align-items:center;
  margin-top:clamp(32px,2.5vw,40px);
}
.tab-expertise-list{ list-style:none; display:grid; gap:24px; margin:0; padding:0; }
.tab-expertise-list li{ display:flex; gap:14px; align-items:flex-start; }
.tab-expertise-list h4{ font-size:18px; font-weight:800; color:var(--espresso); margin:0 0 4px; }
.tab-expertise-list p{ font-size:16.5px; color:var(--ink-soft); font-weight:500; margin:0; }
/* Opción 2 de Contacto (temporal): solo 3 textos, se pidió +30% de tamaño
   de letra para que se lean mejor junto a la foto — escalado SOLO aquí
   (por id), no afecta a "Cómo evaluamos nuevos proveedores" en Proveedores,
   que usa el mismo componente sin este aumento. */
#contacto-directo-opcion2 .tab-expertise-list h4{ font-size:23.5px; }
#contacto-directo-opcion2 .tab-expertise-list p{ font-size:21.5px; }
/* Con la letra más grande, el punto (pensado para alinear con la primera
   línea nada más) quedaba pegado arriba del título en vez de centrado
   entre el título y su descripción — align-items:center lo centra respecto
   a todo el bloque (título + texto), como se pidió. */
#contacto-directo-opcion2 .tab-expertise-list li{ align-items:center; }
#contacto-directo-opcion2 .tab-expertise-dot{ margin-top:0; }
.tab-expertise-dot{ flex:0 0 auto; width:10px; height:10px; margin-top:7px; border-radius:50%; background:var(--terracotta); }
.tab-expertise-photo{ position:relative; min-height:360px; --corner:44px; border-radius:0 var(--corner) 0 0; overflow:hidden; }
.tab-expertise-img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
@media (max-width:860px){
  .tab-expertise-body{ grid-template-columns:1fr; }
  .tab-expertise-photo{ min-height:240px; order:-1; }
}

/* --scatter: variante para secciones donde se quieren VARIOS logos más
   chicos alrededor, no un único logo grande en una esquina.
   2026-09-24, reescrita de raíz: la versión anterior horneaba las 6 marcas
   como un solo SVG "lienzo" de 1200x700 estirado con `background-size:cover`
   sobre toda la sección — en secciones con contenido opaco en medio
   (la tarjeta sólida de compare2, el mapa+sidebar de `.world-map-band`) la
   mayoría de las marcas terminaban tapadas por ese contenido y solo se veían
   1-2 (las que por coincidencia caían en una franja libre), y en secciones
   MUY altas (como `.world-map-band`, que mide varias pantallas) el
   "cover" las apretaba todas cerca del centro, exactamente donde vive el
   contenido opaco. Ahora son 6 capas de `background-image` INDEPENDIENTES,
   cada una posicionada por PORCENTAJE ajustado a las franjas que SIEMPRE
   están libres en cualquier sección (el 3-4% superior, bajo el título, y el
   3% inferior, después del contenido) — nunca en el centro, sin importar
   cuánto mida la sección ni qué tan alta sea. */
.brand-marks-scatter{ position:relative; overflow:hidden; }
.brand-marks-scatter::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-repeat:no-repeat;
  background-image:
    url("../img/isotipo-tenue-0.png"),
    url("../img/isotipo-tenue-1.png"),
    url("../img/isotipo-tenue-2.png"),
    url("../img/isotipo-tenue-3.png"),
    url("../img/isotipo-tenue-4.png"),
    url("../img/isotipo-tenue-5.png");
  background-size:90px,70px,110px,64px,80px,64px;
  background-position:
    3% 3%,
    97% 4%,
    50% 2%,
    3% 97%,
    97% 96%,
    50% 98%;
}

/* ============ SECCIÓN I — "Hover Reveal Cards" ============
   2026-09-24, portado del componente React/Tailwind que mandó el cliente
   (grid de fotos, al pasar el mouse una se agranda/enfoca y las demás se
   atenúan/difuminan). Pedido de ubicación: un lugar MUY VISIBLE, no hasta
   abajo — se usó en Empresa "Nuestro ecosistema" (justo debajo del hero),
   reemplazando el `.cats-grid` repetitivo. Puro CSS, sin JS: el efecto de
   atenuar "a los demás" cuando el mouse está sobre uno se logra con
   `:hover` en el grid + `:not(:hover)` en los hermanos. El título siempre
   se ve; el párrafo y el levantamiento del título solo aparecen en hover,
   como pidió el cliente ("que suba el título y salga el texto"). */
.hover-reveal-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; margin-top:46px; }
.hr-card{
  position:relative; overflow:hidden; min-height:440px; cursor:pointer;
  --corner:44px; border-radius:0 var(--corner) 0 0;
  background-size:cover; background-position:center;
  transition:transform .45s var(--ease), filter .45s var(--ease), opacity .45s var(--ease);
}
.hover-reveal-grid:hover .hr-card{ transform:scale(.97); filter:blur(1.5px); opacity:.6; }
.hover-reveal-grid:hover .hr-card:hover{ transform:scale(1.02); filter:none; opacity:1; z-index:2; box-shadow:0 24px 48px rgba(11,43,32,.32); }
.hr-card::before{
  content:""; position:absolute; inset:0;
  background:linear-gradient(to top, rgba(29,26,20,.88) 0%, rgba(29,26,20,.2) 58%, transparent 100%);
}
.hr-card-inner{ position:absolute; left:0; right:0; bottom:0; z-index:1; padding:28px 26px; }
.hr-card-inner h3{
  color:var(--cream); margin:0; font-size:20px; transition:transform .4s var(--ease);
}
.hr-card-inner p{
  color:var(--cream-2); font-size:17px; line-height:1.5; margin:0; max-height:0; opacity:0;
  overflow:hidden; transition:max-height .4s var(--ease), opacity .3s ease, margin-top .4s var(--ease);
}
.hr-card:hover .hr-card-inner h3{ transform:translateY(-4px); }
/* 210px (antes 140px): con 4 columnas, en los anchos donde la tarjeta se
   angosta el párrafo envuelve a más líneas de las que cabían en 140px y
   quedaba cortado a la mitad (overflow:hidden). 210px cubre incluso el
   párrafo más largo de las 4 tarjetas aun en la columna más angosta. Como
   el bloque de texto cuelga desde abajo (.hr-card-inner{bottom:0}), esto
   también sube el punto donde arranca el texto, no solo evita el corte. */
.hr-card:hover .hr-card-inner p{ max-height:210px; opacity:1; margin-top:10px; }
@media (max-width:980px){
  .hover-reveal-grid{ grid-template-columns:1fr 1fr; }
}
@media (max-width:640px), (hover:none){
  .hover-reveal-grid{ grid-template-columns:1fr; }
  .hr-card{ min-height:280px; }
  /* Sin mouse real (touch), no hay hover — el texto se muestra siempre. */
  .hr-card-inner p{ max-height:140px; opacity:1; margin-top:10px; }
  .hover-reveal-grid:hover .hr-card{ transform:none; filter:none; opacity:1; }
}

/* ============ SECCIÓN J — "Powerful Features" ============
   2026-09-24: grid de 3 tarjetas con un bloque de color sólido/degradado
   arriba (con una mini-ilustración simple dentro) y título+párrafo debajo,
   ya fuera del bloque de color — pedido del cliente sobre esta referencia:
   "dinamismo a los colores, tú elige dependiendo de los colores de la
   marca" (mismo criterio que .compare2: colores DENTRO del logo, uno
   distinto por tarjeta, no el mismo tono repetido 3 veces).
   1er uso: Calidad "Trazabilidad y documentación". 2º uso: Calidad
   "Respaldo y cumplimiento". */
.pf-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:28px; margin-top:46px; }
.pf-card{ display:flex; flex-direction:column; }
.pf-card-visual{
  --corner:36px; border-radius:0 var(--corner) 0 0;
  min-height:168px; display:flex; align-items:center; justify-content:center;
  padding:24px;
}
.pf-card-visual svg{ width:56px; height:56px; }
.pf-card--gold .pf-card-visual{ background:linear-gradient(135deg, var(--gold) 0%, #5E8A28 100%); }
.pf-card--terracotta .pf-card-visual{ background:linear-gradient(135deg, var(--terracotta) 0%, #1F6A3A 100%); }
.pf-card--espresso .pf-card-visual{ background:linear-gradient(135deg, var(--espresso) 0%, #06150F 100%); }
.pf-card h3{ margin:20px 0 0; font-size:20px; font-weight:800; }
.pf-card p{ margin:8px 0 0; font-size:18px; color:var(--ink-soft); font-weight:500; }
.pf-tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:14px; }
.pf-tags span{
  font-size:12.5px; font-weight:700; padding:5px 12px; border-radius:20px;
  background:var(--cream-2); color:var(--espresso);
}
@media (max-width:900px){
  .pf-grid{ grid-template-columns:1fr; gap:22px; }
}

/* ============ SECCIÓN C — "Diagonal del logo, se abre" ============
   2026-09-24, primer y único uso (patrón reservado desde 2026-09-23,
   "forma que se abre, mitad del logo VOLT en diagonal"). El panel oscuro
   izquierdo está recortado con un corte diagonal (mismo criterio de
   ángulo que las esquinas curvas de marca) y contiene el isotipo de VOLT
   a gran tamaño; al entrar en pantalla (reusa el mismo `.reveal`/`.in` de
   IntersectionObserver ya genérico del sitio, en vez de JS nuevo) el panel
   se desliza desde la izquierda hasta su posición — el "se abre". Pedido
   del cliente: usarla en una sección PENDIENTE de rediseño con suficiente
   texto para llenarla — elegido Proveedores "¿Por qué trabajar con VOLT?"
   (de paso resuelve una de las 3 instancias duplicadas de `.cats-grid`). */
.diag-split{ position:relative; overflow:hidden; padding:clamp(40px,3.4vw,60px) 0; }
.diag-split-inner{ display:grid; grid-template-columns:.85fr 1.15fr; align-items:stretch; min-height:440px; }
.diag-panel{
  position:relative; background:var(--espresso); display:flex; align-items:center; justify-content:center;
  clip-path:polygon(0 0, 100% 0, 76% 100%, 0 100%);
  transition:clip-path .9s var(--ease), translate .9s var(--ease);
  translate:-14% 0;
}
.diag-panel.in{ translate:0 0; }
.diag-panel svg{ width:52%; max-width:170px; }
.diag-content{ display:flex; flex-direction:column; justify-content:center; padding:0 clamp(24px,4vw,64px); margin-left:-7%; position:relative; z-index:1; }
.diag-content > p{ color:var(--ink-soft); font-size:18px; font-weight:500; max-width:56ch; margin:14px 0 32px; }
.diag-list{ list-style:none; display:grid; gap:22px; margin:0; padding:0; }
.diag-list li{ display:flex; gap:14px; align-items:flex-start; }
.diag-check{
  flex:0 0 auto; width:26px; height:26px; margin-top:2px; border-radius:50%; background:var(--gold);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/55% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/55% no-repeat;
}
.diag-list h3{ font-size:17px; margin-bottom:4px; }
.diag-list p{ font-size:17px; color:var(--ink-soft); font-weight:500; margin:0; }
@media (max-width:860px){
  .diag-split-inner{ grid-template-columns:1fr; }
  .diag-panel{ clip-path:none; --corner:40px; border-radius:0 var(--corner) 0 0; min-height:200px; translate:0 -14%; }
  .diag-content{ margin-left:0; padding:32px 0 0; }
}

/* ============ SECCIÓN K — "El logo se abre" ============
   2026-09-24, 3ª corrección — revisado un 3er video (24 fotogramas, cada
   ~0.9s) mandado específicamente para verificar qué pasa al subir/bajar el
   scroll. Confirmado: SÍ está atado al scroll (SÍ es sticky/pin — el header
   se sigue viendo colapsar detrás mientras la tarjeta se queda quieta en
   pantalla, prueba de que el bloque está fijo dentro de un contenedor alto)
   — lo que estaba mal en la versión anterior no era usar sticky, sino que
   el tamaño de la máscara crecía LINEAL con el scroll, sin ningún
   "colchón": el primer pixel de scroll hacia arriba ya la empezaba a
   cerrar. Ahora la función de progreso tiene 3 tramos (calculados en JS,
   función `easeHold`): 0→0.28 abre rápido, 0.28→0.72 se QUEDA abierta
   (colchón/aguante, esto es lo nuevo), 0.72→1 cierra rápido — así hay un
   tramo largo de scroll donde se puede leer el contenido sin que nada se
   mueva, y solo cierra si de verdad sigues subiendo mucho más allá de la
   sección (mismo comportamiento reversible del video: cierra y se puede
   volver a abrir si bajas de nuevo).
   Dos variantes según cuánto llega a crecer la máscara al terminar de
   abrir:
   - `.logo-reveal--full` (Calidad "Respaldo y cumplimiento"): la máscara
     crece tanto que cubre TODO el recuadro — se ve una foto rectangular
     normal, sin rastro del logo, dando el máximo espacio de texto posible
     (pedido explícito: "necesito más espacio para el texto").
   - `.logo-reveal` sin modificador (Home, 2º uso): la máscara para de
     crecer ANTES de cubrir el recuadro completo — se queda la silueta de
     las "2 montañas" separadas con un hueco en medio (el efecto que al
     cliente le gustó desde el principio). En este uso además la franja de
     cifras de Home ("20+ años...") vive DENTRO de esta misma `<section>`,
     debajo de la tarjeta — el cliente pidió explícitamente que fuera todo
     una sola sección, no dos separadas. */
/* 200vh → 140vh → 160vh: primer ajuste (140vh) dejó muy poco "colchón"
   fijo después de abrirse del todo — el cliente probó en vivo y hay que
   atinarle justo para alcanzar a leer antes de que la sección suelte el
   scroll. Se sube un poco (no al 200vh original) para dar más margen de
   lectura sin perder la reducción de recorrido ya lograda. */
.logo-reveal-scene{ position:relative; height:160vh; }
/* Home: versión completamente ESTÁTICA (sin scroll-pin) — pedido explícito
   del cliente tras la auditoría de la consultora ("extensión visual de
   Home" / "si alguien ve solo una pantalla, ¿entiende el sector?"). Se deja
   la animación de scroll únicamente en Calidad; aquí el logo se muestra ya
   abierto desde que entra en pantalla (mismo criterio que el fallback
   móvil de abajo, aplicado también en escritorio para esta instancia). */
.logo-reveal-scene--static{ height:auto; }
.logo-reveal-scene--static .logo-reveal{ position:static; height:auto; max-height:none; min-height:560px; }
.logo-reveal-scene--static .logo-reveal-card{ opacity:1; translate:none; }
.logo-reveal{
  position:sticky; top:96px; height:calc(100vh - 140px); max-height:680px;
  border-radius:0 56px 0 0; overflow:hidden; background:var(--cream-2);
  display:flex; flex-direction:column;
}
/* --full (Calidad): "el efecto se ve muy grande" — se reduce la altura del
   recuadro para que no domine tanto la pantalla. */
.logo-reveal--full{ max-height:560px; }
/* Home (2 montañas): al revés — "no tan pequeño el efecto" — recuadro más
   alto para que las montañas tengan más espacio y se vean grandes. */
.logo-reveal-scene--tall{ height:230vh; }
.logo-reveal-scene--tall .logo-reveal{ max-height:820px; }
.logo-reveal-photo{
  position:absolute; inset:0; background-size:cover; background-position:center; --r:0px;
  -webkit-mask:var(--m-hojas) no-repeat center/60px auto, radial-gradient(circle at 50% 50%, #000 var(--r), transparent calc(var(--r) + 1px)) no-repeat center/100% 100%;
  mask:var(--m-hojas) no-repeat center/60px auto, radial-gradient(circle at 50% 50%, #000 var(--r), transparent calc(var(--r) + 1px)) no-repeat center/100% 100%;
}
.logo-reveal{ align-items:center; justify-content:center; }
.logo-reveal-card{
  position:relative; z-index:2; max-width:460px; margin:24px;
  background:rgba(11,43,32,.78); backdrop-filter:blur(2px);
  padding:clamp(24px,3vw,40px); border-radius:0 32px 0 0; color:var(--cream);
  opacity:0; translate:0 12px; transition:opacity .4s var(--ease), translate .4s var(--ease);
}
.logo-reveal.is-open .logo-reveal-card{ opacity:1; translate:0 0; }
/* --center (Home): un solo recuadro centrado en el hueco entre las 2
   montañas — pedido del cliente en vez de la tarjeta a la izquierda +
   franja de cifras aparte abajo ("hazme un único cuadro que esté todo
   centrado, un rectángulo, y ahí que se guarde todo"). */
.logo-reveal-card--center{ max-width:920px; width:90%; text-align:center; }
.logo-reveal-card--center .btn{ margin:0 auto; }
/* --full: tarjeta más ancha (más texto cabe) ya que la foto de fondo se ve
   completa, no hay que dejarle espacio a las 2 montañas. */
.logo-reveal--full .logo-reveal-card{ max-width:620px; margin:24px; text-align:left; }
.logo-reveal-card h2{ color:var(--cream); font-size:clamp(26px,2.6vw,36px); }
.logo-reveal-card > p{ color:var(--cream-2); margin:14px 0 24px; font-size:18px; line-height:1.5; }
.logo-reveal-h2-split{ margin-bottom:24px; }
.logo-reveal-h2-split span{ display:block; color:var(--cream-2); font-size:18px; line-height:1.5; font-weight:500; margin-top:14px; }
.logo-reveal-list{ list-style:none; display:grid; gap:16px; margin:0 0 24px; padding:0; }
.logo-reveal-list li{ display:flex; gap:12px; align-items:flex-start; }
.logo-reveal-list h4{ color:var(--cream); font-size:19px; font-weight:800; margin:0 0 4px; }
.logo-reveal-list p{ color:var(--cream-2); font-size:17.5px; margin:0; font-weight:500; }
.lr-dot{ flex:0 0 auto; width:9px; height:9px; margin-top:6px; border-radius:50%; background:var(--gold); }
/* Franja de cifras — ahora vive DENTRO del mismo recuadro centrado (uso de
   Home), no aparte abajo. */
.logo-reveal-stats{ margin-top:24px; padding-top:20px; border-top:1px solid rgba(247,251,240,.18); }
.logo-reveal-stats .stats-grid{ display:flex; flex-wrap:wrap; justify-content:center; gap:20px 28px; }
.logo-reveal-stats .stat-num{ font-size:clamp(20px,1.8vw,28px); }
.logo-reveal-stats .stat-label{ font-size:14.5px; max-width:18ch; }
@media (max-width:760px){
  .logo-reveal-scene{ height:auto; }
  .logo-reveal{ position:static; height:auto; max-height:none; min-height:560px; }
  .logo-reveal-photo{ -webkit-mask-size:2000px !important; mask-size:2000px !important; }
  .logo-reveal-card{ opacity:1; translate:none; max-width:none; margin:16px; }
  .logo-reveal-stats{ margin-top:16px; }
}

/* ===== Chino simplificado (zh) — TEST 001 =====
   Pila tipográfica: primero la fuente propia (alojada en el servidor, se carga
   solo cuando la página está en chino), luego las fuentes nativas de cada sistema
   operativo (Windows/Mac/Android/iOS), que ya existen en el equipo del visitante
   y por tanto funcionan aunque Google esté bloqueado. */
html[lang="zh"]{
  --display: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", sans-serif;
  --sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", "Noto Sans CJK SC", "Source Han Sans SC", sans-serif;
}
html[lang="zh"] body{ line-height:1.75; letter-spacing:.02em; }
html[lang="zh"] h1, html[lang="zh"] h2, html[lang="zh"] h3, html[lang="zh"] h4{ letter-spacing:.01em; line-height:1.35; }
html[lang="zh"] .brand-word{ letter-spacing:0; }
/* Chino: piso de legibilidad — los caracteres a 11px pierden trazos. Botones del hero de portada y títulos del menú desplegable suben a un mínimo cómodo; el resto del sitio ya queda ≥13px. */
/* (el piso de 13px del botón del hero ya aplica a todos los idiomas, ver .hero-actions .btn) */
html[lang="zh"] .mega-col h6{ letter-spacing:.04em; }

/* Campo trampa anti-spam de los formularios: fuera de pantalla, invisible para personas y lectores de pantalla. */
.hp-field{ position:absolute !important; left:-9999px !important; top:auto !important; width:1px !important; height:1px !important; opacity:0 !important; overflow:hidden !important; pointer-events:none !important; }

/* Página legal (Aviso de privacidad): una sola columna de lectura sobre fondo claro. */
.legal-page{ background:var(--white); padding:clamp(172px,15vw,200px) 0 clamp(56px,6vw,96px); }
.legal-wrap{ width:100%; max-width:1120px; margin:0 auto; }
.legal-wrap .breadcrumb{ justify-content:flex-start; margin:0 0 clamp(36px,5vw,64px); color:var(--ink-soft); font-size:13.5px; }
.legal-wrap .breadcrumb a{ color:var(--ink-soft); }
.legal-wrap .breadcrumb a:hover{ color:var(--espresso); }
.legal-wrap .breadcrumb span{ color:var(--ink-soft); }
.legal-wrap .breadcrumb span:last-child{ color:var(--espresso); font-weight:700; }
.legal-wrap h1{ font-size:clamp(30px,3.2vw,46px); line-height:1.12; font-weight:800; color:var(--espresso); margin:0 0 26px; }
.legal-wrap h2{ font-size:clamp(21px,1.9vw,26px); line-height:1.25; font-weight:800; color:var(--espresso); margin:40px 0 14px; }
.legal-wrap p{ font-size:17.5px; line-height:1.7; color:var(--ink); margin:0 0 16px; }
.legal-wrap ul{ margin:0 0 18px; padding:0 0 0 24px; }
.legal-wrap li{ font-size:17.5px; line-height:1.7; color:var(--ink); margin:0 0 8px; }
.legal-wrap li::marker{ color:var(--terracotta); }
.legal-wrap p a{ color:var(--terracotta-dark); text-decoration:underline; text-underline-offset:3px; font-weight:600; }
.legal-wrap p a:hover{ color:var(--espresso); }
@media (max-width:900px){
  .legal-page{ padding:136px 0 56px; }
  .legal-wrap h2{ margin-top:32px; }
  .legal-wrap p, .legal-wrap li{ font-size:16.5px; }
}

.tab-expertise-list a{ color:var(--terracotta-dark); font-weight:600; text-decoration:underline; text-underline-offset:3px; }
.tab-expertise-list a:hover{ color:var(--espresso); }

.err-wrap{ text-align:left; }
.legal-wrap p.err-code{ font-family:var(--display); font-weight:800; font-size:clamp(84px,14vw,170px); line-height:.9; color:var(--terracotta); margin:0 0 12px !important; letter-spacing:-.02em; }
.err-actions{ display:flex; flex-wrap:wrap; align-items:center; gap:14px 22px; margin-top:28px; }
.err-page .err-actions .btn-text{ color:var(--espresso); }
.err-page .legal-wrap p{ max-width:60ch; }


/* ============ Logo de VOLT en el encabezado y el pie ============ */
.brand-logo{ display:block; height:44px; width:auto; flex:0 0 auto; }
.footer-brand .brand-logo{ height:52px; }
@media (max-width:600px){ .brand-logo{ height:36px; } }
.brand-logo--w{ display:none; }
body.home .site-header .brand-logo--c{ display:none; } body.home .site-header .brand-logo--w{ display:block; }
.site-header.scrolled .brand-logo--c{ display:none; } .site-header.scrolled .brand-logo--w{ display:block; }


/* ============ Países con operación: banderas (reemplaza al mapamundi) ============ */
.flag-grid{ list-style:none; margin:clamp(28px,3vw,44px) auto 0; padding:0; max-width:1080px;
  display:flex; flex-wrap:wrap; justify-content:center; align-items:flex-start; gap:clamp(22px,3vw,40px) clamp(18px,2.4vw,34px); }
.flag-card{ width:clamp(120px,15vw,168px); display:flex; flex-direction:column; align-items:center; gap:12px; text-align:center; }
.flag-wrap{ display:flex; align-items:center; justify-content:center; width:100%; aspect-ratio:3/2; }
.flag-img{ display:block; width:100%; height:100%; object-fit:cover; border-radius:6px; box-shadow:0 8px 24px rgba(0,0,0,.28); }
.flag-wrap--trio{ gap:5%; }
/* Latinoamérica y Asia: varias banderas en una tarjeta más ancha, 3 por fila y de buen tamaño */
.flag-card--multi{ width:clamp(250px,25vw,350px); }
.flag-wrap--multi{ aspect-ratio:auto; flex-wrap:wrap; gap:clamp(8px,1vw,12px); }
.flag-wrap--multi .flag-img{ width:calc((100% - 2 * clamp(8px,1vw,12px)) / 3); height:auto; aspect-ratio:3/2; border-radius:5px; box-shadow:0 6px 18px rgba(0,0,0,.28); }
.flag-wrap--trio .flag-img{ width:30%; height:auto; aspect-ratio:3/2; border-radius:4px; box-shadow:0 6px 16px rgba(0,0,0,.28); }
.flag-name{ font-family:var(--display); font-weight:700; font-size:16.5px; color:var(--cream); letter-spacing:.01em; }
.flags-band .section-head p{ display:none; }
